POJ-2289 Jamie's Contact Groups

二分图多重匹配+二分

对于每个组设置匹配上限,然后用二分图多重匹配看能否全部匹配好

直到找到最小的上限,这就是最大的组的最小值,这个过程可以用二分来优化

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<sstream>
using namespace std;
typedef long long ll;
const int N=1000+10;
const int M=500+10;
const int INF=0x7f7f7f7f;
int uN,vN;
int g[N][M];
int linker[N][M];
bool used[M];
int num[M];
bool dfs(int u)
{
    for(int v=0;v<vN;v++)
        if(g[u][v]&&!used[v])
        {
            used[v]=true;
            if(linker[v][0]<num[v])
            {
                linker[v][++linker[v][0]]=u;
                return true;
            }
            for(int i=1;i<=num[0];i++)
                if(dfs(linker[v][i]))
                {
                    linker[v][i]=u;
                    return true;
                }
        }
    return false;
}
int hungary()
{
    int res=0;
    for(int i=0;i<vN;i++)
        linker[i][0]=0;
    for(int u=0;u<uN;u++)
    {
        memset(used,false,sizeof(used));
        if(dfs(u)) res++;
    }
    return res;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0) break;
        getchar();
        memset(g,0,sizeof(g));
        for(int i=0;i<n;i++)
        {
            string s;
            stringstream ss;
            getline(cin,s);
            ss<<s;
            ss>>s;
            int a;
            while(ss>>a)
                g[i][a]=1;
        }
        uN=n;vN=m;
        int ans=n,l=1,r=n;
        while(l<r)
        {
            int m=(l+r)>>1;
            for(int v=0;v<vN;v++)
                num[v]=m;
            int num=hungary();
            if(num<n)
            {
                l=m+1;
            }
            else
            {
                r=m;
                ans=m;
            }
        }
        int m=(l+r)>>1;
        memset(num,m,sizeof(num));
        int num=hungary();
        if(num==n) ans=m;
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wl16wzl/article/details/83240534
今日推荐