nyoj239 月老的难题 二分图 匈牙利算法
月老的难题
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
-
月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。
现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。
现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。
假设男孩们分别编号为1~n,女孩们也分别编号为1~n。
- 输入
- 第一行是一个整数T,表示测试数据的组数(1<=T<=400)
每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n。(n<=500,K<=10 000)
随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n) - 输出
- 对每组测试数据,输出最多可能促成的幸福家庭数量
- 样例输入
-
1 3 4 1 1 1 3 2 2 3 2
- 样例输出
-
2
View Code#include<stdio.h> #include<string.h> #define N 10010 #define M 510 int num; int link[M]; int head[M],next[N],key[N]; bool use[M]; void add(int u,int v) { key[num]=v; next[num]=head[u]; head[u]=num++; } bool find(int u) { int i,temp; for(i=head[u];i!=-1;i=next[i]) { temp=key[i]; if(!use[temp]) { use[temp]=true; if(link[temp]==-1||find(link[temp])) { link[temp]=u; return true; } } } return false; } int main() { int T,i,a,b,n,k,ans; scanf("%d",&T); while(T--) { memset(link,-1 ,sizeof(link)); memset(head,-1,sizeof(head)); num=0; scanf("%d%d",&n,&k); for(i=0;i<k;++i) { scanf("%d%d",&a,&b); add(a,b); } ans=0; for(i=1;i<=n;++i) { memset(use,false,sizeof(use)); if(find(i)) ans++; } printf("%d\n",ans); } return 0; }
真想骂娘啦,一个变量搞错,WA了两个小时,还是对算法的不够熟悉造成的。
这个题的特别之处是男女编号相同,在构建增广路的时候,比较特别:用hash图存储了