hdu 2255 奔小康赚大钱 KM模板题目
http://acm.hdu.edu.cn/showproblem.php?pid=2255
O(n^4)模板
#include <cstdio> #include <cstring> #include <iostream> #define maxn 301 using namespace std; const int inf = 99999999; int w[maxn][maxn],link[maxn]; int lx[maxn],ly[maxn]; bool vtx[maxn],vty[maxn]; int nx,ny; bool dfs(int i) { int j; vtx[i] = true; for (j = 0; j < ny; ++j) { if (!vty[j] && lx[i] + ly[j] == w[i][j]) { vty[j] = true; if (link[j] == -1 || dfs(link[j])) { link[j] = i; return true; } } } return false; } int KM() { int i,j,k; for (i = 0; i < nx; ++i) { for (j = 0,lx[i] = -inf; j < ny; ++j) { lx[i] = max(lx[i],w[i][j]); } } for (i = 0; i < maxn; ++i) { link[i] = -1; ly[i] = 0; } for (i = 0; i < nx; ++i) { while (1) { for (j = 0; j < maxn; ++j) vtx[j] = vty[j] = false; if (dfs(i)) break; int d = inf; for (j = 0; j < nx; ++j) { if (vtx[j]) { for (k = 0; k < ny; ++k) { if (!vty[k]) d = min(d,lx[j] + ly[k] - w[j][k]); } } } if (d == inf) return -1; for (j = 0; j < nx; ++j) if (vtx[j]) lx[j] -= d; for (j = 0; j < ny; ++j) if (vty[j]) ly[j] += d; } } int sum = 0; for (i = 0; i < ny; ++i) if (link[i] > -1) sum += w[link[i]][i]; return sum; } int main() { int i,j; while (~scanf("%d",&nx)) { ny = nx; memset(w,0,sizeof(w)); for (i = 0; i < nx; ++i) { for (j = 0; j < ny; ++j) { scanf("%d",&w[i][j]); } } printf("%d\n",KM()); } return 0; }