HDU 2255 奔小康赚大钱(KM算法)
最大的二分图带权匹配,KM算法模版题,抄的别人的。
1 #include <iostream> 2 #include <cstring> 3 #include <string> 4 #include <cstdio> 5 using namespace std; 6 #define N 301 7 #define INF 0x7fffffff 8 int mat[N][N]; 9 int match[N]; 10 int inx[N],iny[N]; 11 int lx[N],ly[N]; 12 int n; 13 int dfs(int u) 14 { 15 int i; 16 inx[u] = 1; 17 for(i = 1;i <= n;i ++) 18 { 19 if(!iny[i]&&lx[u] + ly[i] == mat[u][i]) 20 { 21 iny[i] = 1; 22 if(match[i] == -1||dfs(match[i])) 23 { 24 match[i] = u; 25 return 1; 26 } 27 } 28 } 29 return 0; 30 31 } 32 void KM() 33 { 34 int i,j,k,temp; 35 memset(lx,0,sizeof(lx)); 36 memset(ly,0,sizeof(ly)); 37 for(i = 1;i <= n;i ++) 38 { 39 for(j = 1;j <= n;j ++) 40 lx[i] = max(mat[i][j],lx[i]); 41 } 42 for(i = 1;i <= n;i ++) 43 { 44 for(;;) 45 { 46 memset(inx,0,sizeof(inx)); 47 memset(iny,0,sizeof(iny)); 48 if(dfs(i)) 49 break; 50 else 51 { 52 temp = INF; 53 for(j = 1;j <= n;j ++) 54 { 55 if(inx[j]) 56 { 57 for(k = 1;k <= n;k ++) 58 { 59 if(!iny[k]&&temp > lx[j]+ly[k] - mat[j][k]) 60 temp = lx[j]+ly[k] - mat[j][k]; 61 } 62 } 63 } 64 for(j = 1;j <= n;j ++) 65 { 66 if(inx[j]) 67 lx[j] -= temp; 68 if(iny[j]) 69 ly[j] += temp; 70 } 71 } 72 } 73 } 74 } 75 int main() 76 { 77 int i,j; 78 while(scanf("%d",&n)!=EOF) 79 { 80 memset(match,-1,sizeof(match)); 81 for(i = 1;i <= n;i ++) 82 { 83 for(j = 1;j <= n;j ++) 84 { 85 scanf("%d",&mat[i][j]); 86 } 87 } 88 KM(); 89 int ans = 0; 90 for(i = 1;i <= n;i ++) 91 ans += mat[match[i]][i]; 92 printf("%d\n",ans); 93 } 94 return 0; 95 }