标签:
多重匹配:一对多的二分图的多重匹配。二分图的多重匹配算法的实现类似于匈牙利算法,对于集合X中的元素xi,找到一个与其相连的元素yi后,检查匈牙利算法的两个条件是否成立,若yi未被匹配,则将#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