月老的难题
时间限制: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图存储了