码迷,mamicode.com
首页 > 其他好文 > 详细

HDU1669 Jamie's Contact Groups (二分+二分图的多重匹配)

时间:2015-08-25 14:22:34      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

多重匹配:一对多的二分图的多重匹配。二分图的多重匹配算法的实现类似于匈牙利算法,对于集合X中的元素xi,找到一个与其相连的元素yi后,检查匈牙利算法的两个条件是否成立,若yi未被匹配,则将
xi,yi匹配。否则,如果与yi匹配的元素已经达到上限,那么在所有与yi匹配的元素中选择一个元素,检查是否能找到一条增广路径,如果能,则让出位置,让xi与yi匹配。
match[i][j]表示X集合中的Xi点与y集合中的j个点相连接(一对多)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<vector>
#include<cstdlib>
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define pb push_back
#define fread(zcc)  freopen(zcc,"r",stdin)
#define fwrite(zcc) freopen(zcc,"w",stdout)
using namespace std;
const int maxn=1005;
const int inf=999999;

char s[100005];
vector<int> G[maxn];
int Nx,limit,cnt[maxn];//cnt数组是记录X集合Xi点 目前已经匹配Y集合里的点的个数
int matching[maxn][505];//这个表示X集合的Xi点与Y集合的cnt个点相连接
bool vis[maxn];
bool dfs(int u){//多重匹配和二分图的一般匹配差不多,还是两个条件
    int N=G[u].size();
    for(int i=0;i<N;i++){
        int v=G[u][i];
        if(vis[v])continue;
        vis[v]=true;
        if(cnt[v]<limit){
            matching[v][cnt[v]++]=u;//没有达到上限,匹配
            return true;
        }else {
            for(int i=0;i<cnt[v];i++){//达到上限,继续查看是否还能找到增广路
                if(dfs(matching[v][i])){
                    matching[v][i]=u;
                    return true;
                }
            }
        }
    }
    return false;
}
bool hungar(){
    cl(cnt,0);
    for(int i=0;i<Nx;i++){
        cl(vis,false);
        if(!dfs(i))return false;
    }
    return true;
}
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)&&(n||m)){
        getchar();
        for(int i=0;i<n;i++){
            gets(s);
            int len=strlen(s);
            for(int j=0;j<len;j++){
                if(s[j]>='0'&&s[j]<='9'){
                    int num=0;
                    while(s[j]>='0'&&s[j]<='9'){
                        num=num*10+s[j]-'0';
                        j++;
                    }
                    G[i].pb(num);
                }
            }
        }
        Nx=n;
        int l=0,r=n;
        while(l<r){///二分答案
           // printf("%d  %d \n",l,r);
            limit=(l+r)/2;
            if(hungar()){
                r=limit;
            }
            else {
                l=limit+1;
            }
        }
        printf("%d\n",r);
        for(int i=0;i<maxn;i++)G[i].clear();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU1669 Jamie's Contact Groups (二分+二分图的多重匹配)

标签:

原文地址:http://blog.csdn.net/u013167299/article/details/47975251

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!