標籤:
月老的難題時間限制: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)
-
輸出
-
對每組測試資料,輸出最多可能促成的幸福家庭數量
-
範例輸入
-
13 41 11 32 23 2
-
範例輸出
-
2
典型的匈牙利演算法模板,但是必須要用鄰接表做,用鄰接矩陣會逾時
#include<stdio.h>#include<string.h>#define MAX 10010int head[MAX],cnt;int vis[MAX],girl[MAX];int n,m;struct node{int u,v;int next;}edge[MAX];void add(int u,int v){edge[cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;}int find(int x){int i,j;for(i=head[x];i!=-1;i=edge[i].next){ int y=edge[i].v; if(!vis[y]) { vis[y]=1; if(girl[y]==0||find(girl[y])) { girl[y]=x; return 1; } }}return 0;}int main(){ int t,i,j; scanf("%d",&t); while(t--) { memset(head,-1,sizeof(head)); memset(girl,0,sizeof(girl)); cnt=0; scanf("%d%d",&n,&m); for(i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); } int sum=0; for(i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(find(i)) sum++; } printf("%d\n",sum); }}
nyoj 239 月老的難題【匈牙利演算法+鄰接表】