和HDU 3488一样的,只不过要判断一下是否有解。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 8 const int maxn = 1000 + 10; 9 const int INF = 0x3f3f3f3f; 10 11 int n, m; 12 13 int W[maxn][maxn], lft[maxn]; 14 int slack[maxn]; 15 int Lx[maxn], Ly[maxn]; 16 bool S[maxn], T[maxn]; 17 18 bool match(int u) 19 { 20 S[u] = true; 21 for(int v = 1; v <= n; v++) if(!T[v]) 22 { 23 int t = Lx[u] + Ly[v] - W[u][v]; 24 if(0 == t) 25 { 26 T[v] = true; 27 if(!lft[v] || match(lft[v])) 28 { 29 lft[v] = u; 30 return true; 31 } 32 } 33 else slack[v] = min(slack[v], t); 34 } 35 36 return false; 37 } 38 39 void update() 40 { 41 int a = INF; 42 for(int i = 1; i <= n; i++) if(!T[i]) a = min(a, slack[i]); 43 for(int i = 1; i <= n; i++) 44 { 45 if(S[i]) Lx[i] -= a; 46 47 if(T[i]) Ly[i] += a; 48 else slack[i] -= a; 49 } 50 } 51 52 void KM() 53 { 54 memset(Ly, 0, sizeof(Ly)); 55 memset(lft, 0, sizeof(lft)); 56 for(int i = 1; i <= n; i++) Lx[i] = -INF; 57 for(int i = 1; i <= n; i++) 58 for(int j = 1; j <= n; j++) Lx[i] = max(Lx[i], W[i][j]); 59 60 for(int i = 1; i <= n; i++) 61 { 62 memset(slack, 0x3f, sizeof(slack)); 63 for(;;) 64 { 65 memset(S, false, sizeof(S)); 66 memset(T, false, sizeof(T)); 67 if(match(i)) break; 68 update(); 69 } 70 } 71 } 72 73 int main() 74 { 75 int T; scanf("%d", &T); 76 for(int kase = 1; kase <= T; kase++) 77 { 78 scanf("%d%d", &n, &m); 79 for(int i = 1; i <= n; i++) 80 for(int j = 1; j <= n; j++) 81 W[i][j] = -INF; 82 for(int i = 0; i < m; i++) 83 { 84 int u, v, d; scanf("%d%d%d", &u, &v, &d); 85 if(W[u][v] < -d) W[u][v] = W[v][u] = -d; 86 } 87 88 KM(); 89 90 bool ok = true; 91 int ans = 0; 92 for(int i = 1; i <= n; i++) 93 { 94 if(W[lft[i]][i] == -INF) { ok = false; break; } 95 ans += W[lft[i]][i]; 96 } 97 printf("Case %d: ", kase); 98 if(!ok) puts("NO"); 99 else printf("%d ", -ans); 100 } 101 102 return 0; 103 }