1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include<bits/stdc++.h> using namespace std;
const int MAXN = 200 + 5; const int MAXM = 1000000 + 5; const int INF = INT_MAX;
queue<int> q; int head[MAXN], to[MAXM], nxt[MAXM], flow[MAXM], cap[MAXM]; int tot = 1; int dep[MAXN], cur[MAXN]; int m, n, s, t;
void addEdge(int u, int v, int c, int f) { tot++; to[tot] = v; nxt[tot] = head[u]; flow[tot] = f; cap[tot] = c; head[u] = tot; }
bool bfs() { memset(dep, 0, sizeof(dep)); while(!q.empty()) q.pop(); q.push(s); dep[s] = 1; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = head[u]; i != 0; i = nxt[i]) { if(cap[i] > flow[i] && dep[to[i]] == 0) { dep[to[i]] = dep[u] + 1; q.push(to[i]); if(to[i] == t) return true; } } } return false; }
int dinic(int u, int f) { if(u == t || f == 0) { return f; } int rest = f; for(int& i = cur[u]; i != 0; i = nxt[i]) { if(cap[i] > flow[i] && dep[to[i]] == dep[u] + 1) { int k = dinic(to[i], min(rest, cap[i] - flow[i])); if(k == 0) { dep[to[i]] = 0; } flow[i] += k; flow[i ^ 1] -= k; rest -= k; if(rest == 0) break; } } return f - rest; }
int main() { scanf("%d%d", &m, &n); s = m + n + 1; t = m + n + 2; int sum = 0; for(int i = 1; i <= m; i++) { int v, p;
scanf("%d", &v); sum += v; addEdge(s, i, v, 0); addEdge(i, s, 0, 0); while(1) { scanf("%d", &p); if(p == 0) break; addEdge(i, p + m, INF, 0); addEdge(p + m, i, 0, 0); } } for(int i = 1; i <= n; i++) { int v;
scanf("%d", &v); addEdge(i + m, t, v, 0); addEdge(t, i + m, 0, 0); } int maxflow = 0; while(bfs()) { memcpy(cur, head, sizeof(head)); maxflow += dinic(s, INF); } printf("%d\n", sum - maxflow);
return 0; }
|