二分图最大匹配
二分图最大权匹配
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int LEN = 1e3 + 5; 4 typedef long long ll; 5 int n, n1, n2, m; 6 const int oo = 1e9; 7 ll ans; 8 namespace KM { 9 int qh, qt; 10 int w[LEN][LEN], q[LEN]; 11 int lx[LEN], ly[LEN], pre[LEN], slk[LEN], nxt[LEN], vx[LEN], mat[LEN], vy[LEN]; 12 void match(int &u) { 13 while (u) { 14 nxt[u] = pre[u]; 15 swap(u, mat[pre[u]]); 16 } 17 } 18 void bfs(int s) { 19 qh = qt = 0; 20 vx[q[++qt] = s] = 1; 21 while (1) { 22 while (qh < qt) { 23 int u = q[++qh]; 24 for (int v = 1; v <= n; v++) { 25 int tmp; 26 if (vy[v] || (tmp = lx[u] + ly[v] - w[u][v]) > slk[v]) continue; 27 pre[v] = u; 28 if (!tmp) { 29 if (!nxt[v]) return match(v); 30 vy[v] = vx[q[++qt] = nxt[v]] = 1; 31 } else slk[v] = tmp; 32 } 33 } 34 int a = oo; 35 for (int i = 1; i <= n; i++) { 36 if (!vy[i] && a > slk[i]) a = slk[s = i]; 37 } 38 for (int i = 1; i <= n; i++) { 39 if (vx[i]) lx[i] -= a; 40 if (vy[i]) ly[i] += a; 41 else slk[i] -= a; 42 } 43 if (!nxt[s]) return match(s); 44 vy[s] = vx[q[++qt] = nxt[s]] = 1; 45 } 46 } 47 void km() { 48 for (int i = 1; i <= n; i++) { 49 for (int j = 1; j <= n; j++) { 50 slk[j] = oo; 51 vx[j] = vy[j] = 0; 52 lx[i] = max(lx[i], w[i][j]); 53 } 54 bfs(i); 55 } 56 ans = 0; 57 for (int i = 1; i <= n; i++) ans += lx[i] + ly[i]; 58 printf("%lld ", ans); 59 for (int i = 1; i < n1; i++) { 60 printf("%d ", w[i][mat[i]] ? mat[i] : 0); 61 } 62 printf("%d ", w[n1][mat[n1]] ? mat[n1] : 0); 63 } 64 } 65 using namespace KM; 66 int main() { 67 scanf("%d %d %d", &n1, &n2, &m); 68 n = max(n1, n2);//左右的点的编号都是从1开始,n为较大的值 69 for (int i = 1; i <= m; i++) { 70 int x, y, z;//表示的是左边的第x个点和右边的第y个点可以花费z匹配 71 scanf("%d %d %d", &x, &y, &z); 72 w[x][y] = max(w[x][y], z); 73 } 74 km(); 75 return 0; 76 }