HDU 3488 KM Tour
这题注意有重边。。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 200 + 10; 7 8 int n, m; 9 int W[maxn][maxn], lft[maxn]; 10 int Lx[maxn], Ly[maxn]; 11 bool S[maxn], T[maxn]; 12 int slack[maxn]; 13 14 bool match(int u) 15 { 16 S[u] = true; 17 for(int v = 1; v <= n; v++) if(!T[v]) 18 { 19 int t = Lx[u] + Ly[v] - W[u][v]; 20 if(0 == t) 21 { 22 T[v] = true; 23 if(!lft[v] || match(lft[v])) 24 { 25 lft[v] = u; 26 return true; 27 } 28 } 29 else slack[v] = min(slack[v], t); 30 } 31 return false; 32 } 33 34 void update() 35 { 36 int a = 100000000; 37 for(int i = 1; i <= n; i++) if(!T[i]) a = min(a, slack[i]); 38 for(int i = 1; i <= n; i++) 39 { 40 if(S[i]) Lx[i] -= a; 41 42 if(T[i]) Ly[i] += a; 43 else slack[i] -= a; 44 } 45 } 46 47 void KM() 48 { 49 memset(lft, 0, sizeof(lft)); 50 memset(Lx, 0x80, sizeof(Lx)); 51 memset(Ly, 0, sizeof(Ly)); 52 for(int i = 1; i <= n; i++) 53 for(int j = 1; j <= n; j++) 54 Lx[i] = max(Lx[i], W[i][j]); 55 56 for(int i = 1; i <= n; i++) 57 { 58 memset(slack, 0x3f, sizeof(slack)); 59 for(;;) 60 { 61 memset(S, false, sizeof(S)); 62 memset(T, false, sizeof(T)); 63 if(match(i)) break; 64 else update(); 65 } 66 } 67 } 68 69 int main() 70 { 71 int T; scanf("%d", &T); 72 73 while(T--) 74 { 75 scanf("%d%d", &n, &m); 76 memset(W, 0x80, sizeof(W)); 77 for(int i = 0; i < m; i++) 78 { 79 int u, v, d; scanf("%d%d%d", &u, &v, &d); 80 W[u][v] = max(W[u][v], -d); 81 } 82 83 KM(); 84 85 int ans = 0; 86 for(int i = 1; i <= n; i++) ans += W[lft[i]][i]; 87 printf("%d\n", -ans); 88 } 89 90 return 0; 91 }