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
| #include <cstdio> #include <queue> #include <cstring>
const int INF = 1e9; inline int min(const int x, const int y) {return x < y ? x : y;} struct Edge { int to, nxt, cap; } e[3000005]; int head[10005], dep[10005], cur[10005], num[10005], tot = 1, s, t, n, m; std::queue<int> Q; inline void AddEdge(const int u, const int v, const int cap) { e[++ tot].to = v, e[tot].cap = cap, e[tot].nxt = head[u], head[u] = tot; e[++ tot].to = u, e[tot].cap = 0, e[tot].nxt = head[v], head[v] = tot; }
void bfs() { memcpy(cur, head, sizeof cur); num[dep[t] = 1] = 1; Q.push(t); while (Q.size()) { int u = Q.front(); Q.pop(); for (int i = head[u]; i; i = e[i].nxt) if (!dep[e[i].to]) ++ num[dep[e[i].to] = dep[u] + 1], Q.push(e[i].to); } } int dfs(const int u, const int flow) { if (u == t) return flow; int used = 0, tmp = 0; for (int i = cur[u]; i; i = e[i].nxt) { cur[u] = i; if (e[i].cap && dep[u] - 1 == dep[e[i].to]) { tmp = dfs(e[i].to, min(e[i].cap, flow - used)); used += tmp, e[i].cap -= tmp, e[i ^ 1].cap += tmp; if (used == flow) return used; } } cur[u] = head[u]; if (!(-- num[dep[u]])) dep[s] = n + m + 2; ++ num[++ dep[u]]; return used; }
int ISAP() { int Maxflow = 0; bfs(); while (dep[s] <= n + m + 1) Maxflow += dfs(s, INF); return Maxflow; }
int main() { int ans = 0; scanf("%d%d", &n, &m); s = 0, t = n + m + 1; for (int i = 1; i <= n; ++ i) { int x, T; scanf("%d%d", &x, &T); ans += x; AddEdge(i + m, t, x); while (T --) { int a, b; scanf("%d%d", &a, &b); AddEdge(a, i + m, b); } } for (int i = 1; i <= m; ++ i) { int x; scanf("%d", &x); AddEdge(s, i, x); } printf("%d\n", ans - ISAP()); return 0; }
|