KM模板
HDU 2255
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 306 int n,e[N][N]; int match[N],slack[N],ea[N],eb[N]; bool va[N],vb[N]; bool dfs(int u) { va[u]=true; int gap; for(int i=1;i<=n;++i) { if(vb[i]) continue; gap=ea[u]+eb[i]-e[u][i]; if(!gap) { vb[i]=true; if(!match[i] || dfs(match[i])) { match[i]=u; return true; } } else slack[i]=min(slack[i],gap); } return false; } void KM() { memset(match,0,sizeof(match)); memset(eb,0,sizeof(eb)); for(int i=1;i<=n;++i) { ea[i]=0; for(int j=1;j<=n;++j) ea[i]=max(ea[i],e[i][j]); } int gap; for(int i=1;i<=n;++i) { fill(slack+1,slack+n+1,0x3f3f3f3f); while(1) { memset(va,false,sizeof(*va)*(n+1)); memset(vb,false,sizeof(*vb)*(n+1)); if(dfs(i)) break; gap=0x3f3f3f3f; for(int j=1;j<=n;++j) if(!vb[j]) gap=min(gap,slack[j]); for(int j=1;j<=n;++j) if(va[j]) ea[j]-=gap; for(int j=1;j<=n;++j) if(vb[j]) eb[j]+=gap; else slack[j]-=gap; } } int sum=0; for(int i=1;i<=n;++i) sum+=e[match[i]][i]; printf("%d\n",sum); } int main() { while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&e[i][j]); KM(); } return 0; }