具体方法就不介绍了,详见 https://blog.csdn.net/sixdaycoder/article/details/47720471
主要讲一些注意点:
1:slack开外面节省时间,因为同一个x在不停循环中slack只会不断变小,被更新
2:因为多组数据,所有数组都记得清零
3:dfs中坑了我20多次MLE……记得visx,visy数组都要更新
4:这种做法仅限于每一个点都能被匹配的情况,若不能都匹配就要用网络流
二分图匹配模板题:(值得思考)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int V,n,m,e; 4 vector<int> v[1005]; 5 int vis[1005],match[1005]; 6 7 int init() 8 { 9 memset(match,-1,sizeof(match)); 10 scanf("%d%d%d%d",&V,&n,&m,&e); 11 for(int i=1;i<=e;i++) 12 { 13 int x,y; 14 scanf("%d%d",&x,&y); y+=n; 15 v[x].push_back(y); 16 } 17 } 18 19 int dfs(int u) 20 { 21 for(int i=0;i<(int)v[u].size();i++) 22 { 23 int p=v[u][i]; 24 if(vis[p]) continue; 25 vis[p]=1; 26 if(match[p]==-1||dfs(match[p])==1) 27 { 28 match[u]=p; 29 match[p]=u; 30 return 1; 31 } 32 } 33 return 0; 34 } 35 36 int main() 37 { 38 int sum=0; 39 init(); 40 for(int i=1;i<=n;i++) 41 { 42 if(match[i]==-1) 43 { 44 memset(vis,0,sizeof(vis)); 45 if (dfs(i)) sum++; 46 } 47 } 48 printf("%d\n",min(V+1,n+m-sum)); 49 return 0; 50 }
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=305; 5 const int inf=0X3f3f3f; 6 7 int w[N][N]; 8 int n,ans=0; 9 int lx[N],ly[N],match[N],slack[N]; 10 bool visx[N],visy[N]; 11 12 13 void init() 14 { 15 for(int i=0;i<n;i++) visy[i]=0; 16 for(int i=0;i<n;i++) visx[i]=0; 17 } 18 19 bool dfs(int u) 20 { 21 int Delta; 22 visx[u]=1; 23 for(int v=0;v<n;++v) 24 { 25 if(visy[v]) continue; 26 Delta=lx[u]+ly[v]-w[u][v]; 27 if(Delta==0) 28 { 29 visy[v]=1; 30 if(match[v]==-1||dfs(match[v])) 31 { 32 match[v]=u; 33 return true; 34 } 35 } 36 else if(slack[v] > Delta) 37 slack[v] = Delta; 38 } 39 return false; 40 } 41 42 void KM() 43 { 44 for(int x=0;x<n;++x) 45 { 46 for(int y=0;y<n;++y) slack[y]=inf;//开外面节省时间 47 while(true) 48 { 49 init(); 50 if(dfs(x)) break; 51 int delta=inf; 52 for(int j=0;j<n;++j) if(!visy[j]&&delta>slack[j]) delta=slack[j]; 53 for(int i=0;i<n;++i) if(visx[i]) lx[i]-=delta; 54 for(int j=0;j<n;++j) 55 { 56 if(visy[j]) ly[j]+=delta; 57 else slack[j]-=delta; 58 } 59 } 60 } 61 } 62 63 int main() 64 { 65 while(scanf("%d",&n)!=EOF) 66 { 67 memset(match,-1,sizeof(match)); 68 memset(ly,0,sizeof(ly)); 69 for(int i=0;i<n;++i) match[i]=-1; 70 for(int i=0;i<n;++i) 71 { 72 for(int j=0;j<n;++j) 73 { 74 scanf("%d",&w[i][j]); 75 } 76 } 77 for(int i=0;i<n;++i) 78 { 79 lx[i]=-inf; 80 for(int j=0;j<n;j++) if(lx[i]<w[i][j]) lx[i]=w[i][j]; 81 } 82 KM(); 83 84 ans=0; 85 for(int i=0;i<n;++i) 86 { 87 if(match[i]!=-1) ans+=w[match[i]][i]; 88 } 89 printf("%d\n",ans); 90 } 91 return 0; 92 }