HDU 1669 Jamie's Contact Groups(多重匹配+二分枚举)

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1669

题目大意:

给你各个人可以属于的组,把这些人分组,使这些组中人数最多的组人数最少,并输出这个人数。
解题思路:

一组可以有多人,一人只能分到一组,显然是多重匹配,只要枚举一下每组的限制人数limit,用多重匹配判断即可。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e3+5;
const int M=5e2+5;

int n,m,limit;
int link[M][N];
bool vis[M];
vector<int>v[N];

bool dfs(int u){
    for(int i=0;i<v[u].size();i++){
        int t=v[u][i];
        if(vis[t]) continue;
        vis[t]=true;
        if(link[t][0]<limit){
            link[t][++link[t][0]]=u;
            return true;
        }
        for(int i=1;i<=limit;i++){
            if(dfs(link[t][i])){
                link[t][i]=u;
                return true;
            }
        }
    }
    return false;
}
//多重匹配
bool mul_match(){
    for(int i=0;i<=m;i++) link[i][0]=0;
    for(int i=0;i<n;i++){
        memset(vis,false,sizeof(vis));
        if(!dfs(i)) return false;
    }
    return true;
}

int main(){
    while(~scanf("%d%d",&n,&m)&&n&&m){
        for(int i=0;i<=n;i++) v[i].clear();
        char op[25];
        for(int i=0;i<n;i++){
            scanf("%s",op);
            int x;
            while(getchar()==' '){
                scanf("%d",&x);
                v[i].push_back(x);
            }
        }
        //二分枚举上限人数
        int l=1,r=1e3,ans=0;
        while(l<=r){
            limit=(l+r)/2;
            if(mul_match()){
                r=limit-1;
                ans=limit;
            }
            else l=limit+1;
        }
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fu3638/p/8785422.html