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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include <bits/stdc++.h> using namespace std; #define clear(a, b) memset (a, b, sizeof(a)) #define copy(a, b) memcpy (a, b, sizeof(a)) const int iol = 1024 * 1024; char buf[iol], *ioh, *iot, ioc; bool iosig; inline char read() { if(ioh == iot) { iot = (ioh = buf) + fread(buf, 1, iol, stdin); if(ioh == iot) return -1; } return *ioh++; } template<class T> inline bool read(T &x) { iosig = false; for (ioc = read(); !isdigit(ioc); ioc = read()) { if (ioc == -1) return false; if (ioc == '-') iosig = true; } x = 0; while(ioc == '0') ioc = read(); for(; isdigit(ioc); ioc = read()) x = (x << 1) + (x << 3) + (ioc ^ '0'); ioh--; if(iosig) x = -x; return true; } const int MAXN = 101000; const int MAXE = 500100; const int INF = 0x3f3f3f3f; struct Edge { int v; int c; int n; } edge[MAXE]; int adj[MAXN], cnt; int dis[MAXN], cur[MAXN], pre[MAXN], num[MAXN]; int s, t, nv; int n, m; inline void addEdge(int u, int v, int c) {
edge[cnt].v = v; edge[cnt].c = c; edge[cnt].n = adj[u]; adj[u] = cnt++; edge[cnt].v = u; edge[cnt].c = 0; edge[cnt].n = adj[v]; adj[v] = cnt++; } inline void bfs(int t) { clear (num, 0), clear (dis, -1); dis[t] = 0; num[0] = 1; queue<int> q; q.push(t); while(!q.empty()) { register int u = q.front(); q.pop(); for(register int i = adj[u], v; ~i; i=edge[i].n) { v=edge[i].v; if(~dis[v]) continue; dis[v] = dis[u] + 1; q.push(v); ++num[dis[v]]; } } } inline int isap(int s, int t, int nv) { copy(cur, adj); bfs(t); int flow = 0, u = pre[s] = s, i; while (dis[t] < nv) { if (u == t) { int f = INF, neck; for (i = s; i != t; i = edge[cur[i]].v) { if (f > edge[cur[i]].c) { f = edge[cur[i]].c; neck = i; } } for (i = s; i ^ t; i = edge[cur[i]].v) { edge[cur[i]].c -= f; edge[cur[i] ^ 1].c += f; } flow += f; u = neck; } for (i = cur[u]; ~i; i = edge[i].n) if (dis[edge[i].v] + 1 == dis[u] && edge[i].c) break; if (~i) { cur[u] = i; pre[edge[i].v] = u; u = edge[i].v; }else { if (0 == (--num[dis[u]])) break; int mind = nv; for (i = adj[u]; ~i; i = edge[i].n) { if (edge[i].c && mind > dis[edge[i].v]) { cur[u] = i; mind = dis[edge[i].v]; } } dis[u] = mind + 1; num[dis[u]]++; u = pre[u]; } } return flow; } #define init() clear(adj, -1), cnt = 0 int tot, ans; int main(){ init(); read(n), read(m); s = tot = ans = 0, t = n << 1 | 1; for (register int i = 1, w; i <= n; i++) read(w), ans += w, addEdge(s, i, w), addEdge(i + n, t, w); for (register int i = 0, u, v, w; i < m; i++) read(u), read(v), read(w), addEdge(u, v + n, w); nv = t - s + 1; s = s, t = t; cout << ans - isap(s, t, nv); return 0; }
|