[hdu2063]过山车(二分图匹配)
题意:每个女人有感兴趣的k个男人,过山车两人一组,求最大匹配数。
解题关键:二分图最大匹配。匈牙利算法求解。
1、链式前向星建图
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<cmath> 7 #define maxn 250020 8 using namespace std; 9 typedef long long ll; 10 int n,m,k,a,b; 11 struct Edge{ 12 int nxt; 13 int to; 14 int w; 15 }e[maxn]; 16 int head[maxn],cnt; 17 void add_edge(int u,int v){ 18 e[cnt].to=v; 19 e[cnt].nxt=head[u]; 20 head[u]=cnt++; 21 } 22 int pre[maxn]; 23 bool vis[maxn]; 24 bool dfs(int u){ 25 for(int i=head[u];i!=-1;i=e[i].nxt){ 26 int v=e[i].to; 27 if(!vis[v]){ 28 vis[v]=true; 29 if(pre[v]==-1||dfs(pre[v])){ 30 pre[v]=u; 31 //pre[u]=v; 32 return true; 33 } 34 } 35 } 36 return false; 37 } 38 39 int hungary(){ 40 int ans=0; 41 memset(pre,-1,sizeof pre); 42 for(int i=1;i<=m;i++) { 43 if(pre[i]==-1) { 44 memset(vis,0,sizeof vis); 45 if(dfs(i)) ans++; 46 } 47 } 48 return ans; 49 } 50 int main(){ 51 while(scanf("%d",&k)!=EOF&&k){ 52 memset(head, -1, sizeof head); 53 cnt=0; 54 scanf("%d%d",&m,&n); 55 for(int i=0;i<k;i++){ 56 scanf("%d%d",&a,&b); 57 add_edge(a,b+m); 58 } 59 int ans=hungary(); 60 printf("%d\n",ans); 61 } 62 return 0; 63 }
2、邻接矩阵建图
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6 #include<cmath> 7 #define maxn 505 8 using namespace std; 9 typedef long long ll; 10 bool G[maxn][maxn]; 11 int pre[maxn]; 12 bool vis[maxn]; 13 int n,m,k; 14 bool dfs(int u){ 15 for(int i=1;i<=n;i++){ 16 if(G[u][i]&&!vis[i]){ 17 vis[i]=true; 18 if(pre[i]==-1||dfs(pre[i])){ 19 pre[i]=u; 20 return true; 21 } 22 } 23 } 24 return false; 25 } 26 27 int hungary(){ 28 int num=0; 29 memset(pre,-1,sizeof pre); 30 for(int i=1;i<=m;i++){ 31 memset(vis,0,sizeof vis); 32 if(dfs(i)) num++; 33 } 34 return num; 35 } 36 int main(){ 37 int u,v; 38 while(scanf("%d",&k)!=EOF&&k){ 39 scanf("%d%d",&m,&n); 40 memset(G,0,sizeof G); 41 for(int i=0;i<k;i++){ 42 scanf("%d%d",&u,&v); 43 G[u][v]=1; 44 } 45 int ans=hungary(); 46 printf("%d\n",ans); 47 } 48 return 0; 49 }