km算法
例题;
http://acm.hdu.edu.cn/showproblem.php?pid=2255
中文题目。。。
代码:
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<stdio.h> using namespace std; # define maxn 500+10 # define inf 0x3f3f3f3f int a[maxn][maxn]; int nx[maxn],ny[maxn]; int visx[maxn],visy[maxn]; int net[maxn]; int slack[maxn]; int n; void init1() { memset(net,0,sizeof(net)); memset(nx,0,sizeof(nx)); memset(ny,0,sizeof(ny)); } void init2() { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); } bool Find(int t) { visx[t]=1; for(int i=1; i<=n; i++) { if(nx[t]+ny[i]-a[t][i]==0) { if(visy[i])continue; visy[i]=1; if(net[i]==0||Find(net[i])) { net[i]=t; return true; } } else slack[i]=min(slack[i],nx[t]+ny[i]-a[t][i]); } return false; } int km() { for(int i=1; i<=n; i++) { memset(slack,inf,sizeof(slack)); while(1) { init2(); if(Find(i))break; int minn=inf; for(int i=1; i<=n; i++) { if(!visy[i])minn=min(minn,slack[i]); } for(int i=1; i<=n; i++) { if(visx[i])nx[i]-=minn; } for(int i=1; i<=n; i++) { if(visy[i])ny[i]+=minn; } } } int sum=0; for(int i=1; i<=n; i++) { sum+=a[net[i]][i]; } return sum; } int main() { while(~scanf("%d",&n)) { init1(); for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d",&a[i][j]); nx[i]=max(nx[i],a[i][j]); } } int t=km(); printf("%d\n",t); } return 0; }