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 97 98 99 100 101 102 103 104 105 106 107
| #include <bits/stdc++.h>
using namespace std;
const int Maxn = 2000 + 10, Maxm = 8000 + 10, S = 2002, T = 2003, inf = 0x3f3f3f3f;
int N, M; int e, Begin[Maxn], To[Maxm], Next[Maxm], W[Maxm];
inline void add_edge (int x, int y, int z) { To[e] = y; Next[e] = Begin[x]; Begin[x] = e; W[e++] = z; }
inline void Link (int x, int y, int z) { add_edge (x, y, z); add_edge (y, x, 0); }
namespace Flow { int Dis[Maxn];
inline int bfs () { queue <int> Q; Q.push(S); memset(Dis, -1, sizeof Dis); Dis[S] = 0; while (!Q.empty()) { int x = Q.front(); Q.pop(); for (int i = Begin[x]; ~i; i = Next[i]) { int y = To[i]; if (W[i] <= 0 || Dis[y] != -1) continue; Dis[y] = Dis[x] + 1; Q.push(y); } } return Dis[T] != -1; }
inline int find (int x, int now) { if (x == T) return now; for (int i = Begin[x]; ~i; i = Next[i]) { int y = To[i], sum; if (W[i] > 0 && Dis[y] == Dis[x] + 1 && (sum = find(y, min(now, W[i])))) { W[i] -= sum; W[i ^ 1] += sum; return sum; } } return 0; }
inline int work () { int ans = 0; while (bfs()) { int sum = 0; while (sum = find(S, inf)) ans += sum; } return ans; } }
int main() { freopen("permutation.in", "r", stdin); freopen("permutation.out", "w", stdout); memset(Begin, -1, sizeof Begin); scanf("%d%d", &N, &M); int sum = 0; for (int i = 1; i <= N; ++i) { int x; scanf("%d", &x); if (x > 0) { sum += x; Link(S, i, x); Link(i + N, T, x); } else { Link(i, i + N, -x); } } for (int i = 1; i <= M; ++i) { int x, y; scanf("%d%d", &x, &y); Link(x, y, inf); Link(x + N, y + N, inf); } printf("%d\n", sum - Flow :: work()); return 0; }
|