KM算法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <bits/stdc++.h> 2 #define N 1500 3 #define inf 999999999 4 using namespace std; 5 int a[N],bs[N],nx=0,ny=0,k; 6 int linky[N],lx[N],ly[N],slack[N]; 7 int visx[N],visy[N],w[N][N]; 8 int min(int a,int b){return (a<b)?a:b;} 9 int find(int x){ 10 visx[x]=1; 11 for(int y=1;y<=ny;y++){ 12 if(visy[y]) continue; 13 int t=lx[x]+ly[y]-w[x][y]; 14 if(t==0){visy[y]=1; 15 if(linky[y]==-1||find(linky[y])){ 16 linky[y]=x;return 1; 17 } 18 } 19 else if(slack[y]>t) slack[y]=t; 20 } 21 return 0; 22 } 23 int km(){ 24 memset(linky,-1,sizeof(linky)); 25 memset(ly,0,sizeof(ly)); 26 for(int i=1;i<=nx;i++) lx[i]=-inf; 27 for(int i=1;i<=nx;i++)for(int j=1;j<=ny;j++)if(w[i][j]>lx[i])lx[i]=w[i][j]; 28 for(int x=1;x<=nx;x++){ 29 for(int i=1;i<=ny;i++) 30 slack[i]=inf; 31 while(1){ 32 memset(visx,0,sizeof(visx)); 33 memset(visy,0,sizeof(visy)); 34 if(find(x)) break; 35 int d=inf; 36 for(int i=1;i<=ny;i++) if(!visy[i]&&d>slack[i]) d=slack[i]; 37 for(int i=1;i<=nx;i++) if(visx[i]) lx[i]-=d; 38 for(int i=1;i<=ny;i++) if(visy[i]) ly[i]+=d; else slack[i]-=d; 39 } 40 } 41 int result=0; 42 for(int i=1;i<=ny;i++) 43 if(linky[i]>-1) result+=w[linky[i]][i]; 44 return result; 45 } 46 int main(){ 47 scanf("%d%d%d",&nx,&ny,&k); 48 for(int i=1;i<=k;i++){ 49 int a,b,c;scanf("%d%d%d",&a,&b,&c); 50 w[a][b]=c; 51 }printf("%d\n",km()); 52 return 0; 53 }
匈牙利算法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cstring> 3 #define N 1010 4 using namespace std; 5 int map[N][N]; 6 int max,x1,m,y1,tot,ans; 7 int used[N],link[N]; 8 int find(int t) 9 { 10 for(int i=1;i<=y1;i++) 11 { 12 if(used[i]==0&&map[t][i]==1) 13 { 14 used[i]=1; 15 if(link[i]==0||find(link[i])) 16 { 17 link[i]=t; 18 return 1; 19 } 20 } 21 } 22 return 0; 23 } 24 int main() 25 { 26 scanf("%d%d%d%d",&max,&x1,&y1,&m); 27 max++;tot=x1+y1; 28 for(int i=1;i<=m;i++) 29 { 30 int a,b; 31 scanf("%d%d",&a,&b); 32 map[a][b]=1; 33 } 34 for(int i=1;i<=y1;i++)link[i]=0; 35 for(int i=1;i<=x1;i++) 36 { 37 for(int i=1;i<=y1;i++) used[i]=0; 38 if(find(i)) 39 ans++; 40 } 41 printf("%d\n",(max<tot-ans)? max:tot-ans); 42 return 0; 43 }