[HDU 2255] 奔小康赚大钱
[题目链接]
http://acm.hdu.edu.cn/showproblem.php?pid=2255
[算法]
KM算法模板题
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 510 const int INF = INT_MAX; int n,i,j,delta; int la[MAXN],lb[MAXN],match[MAXN]; int w[MAXN][MAXN]; bool visiteda[MAXN],visitedb[MAXN]; inline bool dfs(int u) { int v; visiteda[u] = true; for (v = 1; v <= n; v++) { if (!visitedb[v]) { if (la[u] + lb[v] == w[u][v]) { visitedb[v] = true; if (!match[v] || dfs(match[v])) { match[v] = u; return true; } } else delta = min(delta,la[u] + lb[v] - w[u][v]); } } return false; } inline int KM() { int i,j,ret; memset(match,0,sizeof(match)); for (i = 1; i <= n; i++) { la[i] = -INF; lb[i] = 0; for (j = 1; j <= n; j++) la[i] = max(la[i],w[i][j]); } for (i = 1; i <= n; i++) { while (true) { delta = INF; for (j = 1; j <= n; j++) visiteda[j] = visitedb[j] = false; if (dfs(i)) break; for (j = 1; j <= n; j++) { if (visiteda[j]) la[j] -= delta; if (visitedb[j]) lb[j] += delta; } } } ret = 0; for (i = 1; i <= n; i++) ret += w[match[i]][i]; return ret; } int main() { while (scanf("%d",&n) != EOF) { for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { scanf("%d",&w[i][j]); } } printf("%d\n",KM()); } return 0; }