现在的位置: 首页 > 综合 > 正文

POJ–2289–Jamie’s Contact Groups【二分图多重匹配+二分答案】

2018年01月12日 ⁄ 综合 ⁄ 共 1416字 ⁄ 字号 评论关闭

链接:http://poj.org/problem?id=2289

题意:有n个人,m个分组,每个人可以分配到一些组别,问如何分能使得人数最多的组别人数最少。

思路:这道题二分+网络流也可以做,我这里是二分图多重匹配的做法。因为一个组别是一对多的关系,所以是多重匹配,我们二分多重匹配的限制,得到最小的限制可使二分图匹配,这个限制就是答案。

网上找的模板

#include<cstring>
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 500010
#define eps 1e-6
#define INF 0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1


const int M=2010;
int bmap[M][M]; //下标0开始
bool bmask[M];
int nx,ny;
int vcy[M];
int cy[M][M];
int limit;  //多重匹配限制
bool findpath(int u){
    int i,j;
    for(i = 0; i < ny; i++){
        if(bmap[u][i] && !bmask[i]){
            bmask[i] = 1;
            if(vcy[i] < limit){
                cy[i][vcy[i]++] = u;
                return 1;
            }
            for(j = 0; j < vcy[i]; j++){
                if(findpath(cy[i][j])){
                    cy[i][j] = u;
                    return 1;
                }
            }
        }
    }
    return 0;
}
bool MulMatch(){
    memset(vcy,0,sizeof(vcy));
    for(int i=0; i < nx; i++){
        memset(bmask,0,sizeof(bmask));
        if(!findpath(i)) return 0;
    }
    return 1;
}
char str[5000];
int main(){
    int i,j,x;
    while(scanf("%d%d",&nx,&ny),nx||ny){
        memset(bmap,0,sizeof(bmap));
        for(i = 0; i < nx; i++){
            scanf("%s", str);
            gets(str);
            stringstream sin(str);
            while(sin >> x){
                bmap[i][x] = 1;
            }
        }
        int l = 0, r = nx;
        while(l < r){
            limit = (l + r) / 2;
            if(MulMatch())  r = limit;
            else    l = limit + 1;
        }
        printf("%d\n", r);
    }
    return 0;
}

抱歉!评论已关闭.