constint N = 1005; constint M = 1005; constint INF = 0x3f3f3f3f;
namespace graph { constint SIZE = (N*2+M*2)*4; structedge { int to, flow, next; } e[M*2]; int head[N], ecnt = 1; int dis[N], cur[N]; int S, T; intdinic(); boolbfs(int S, int T); intdfs(int x, int flow); voidinsert(int u, int v, int f); } usingnamespace graph;
#define l(i) (i) #define r(i) (i+n)
int n, m, sum;
intmain() { read(n, m); S = n*2+1, T = n*2+2; for(int i = 1, x; i <= n; i++) { read(x); if(x > 0) { sum += x; insert(S, l(i), x); insert(r(i), T, x); } else insert(l(i), r(i), -x); } for(int i = 1; i <= m; i++) { int a, b; read(a, b); insert(l(a), l(b), INF); insert(r(a), r(b), INF); } print(sum-dinic()); }
namespace graph { intdinic() { int maxflow = 0; while(bfs(S, T) == true) maxflow += dfs(S, INF); return maxflow; } boolbfs(int S, int T) { memset(dis, 0, sizeof(dis)); memcpy(cur, head, sizeof(cur)); queue<int> q; int x; q.push(S); dis[S] = 1; while(q.size()) { x = q.front(); q.pop(); for(int i = head[x]; i; i = e[i].next) { if(e[i].flow and !dis[e[i].to]) { dis[e[i].to] = dis[x]+1; q.push(e[i].to); } } } return dis[T]; } intdfs(int x, int flow) { if(x == T) return flow; int rest = flow, k, i; for(i = cur[x]; i; i = e[i].next) { if(e[i].flow and dis[e[i].to] == dis[x]+1) { k = dfs(e[i].to, min(rest, e[i].flow)); if(k == 0) dis[e[i].to] = -1; e[i].flow -= k, e[i^1].flow += k; if(!(rest -= k)) break; } } return flow-rest; } voidinsert(int u, int v, int f) { e[++ecnt] = {v, f, head[u]}; head[u] = ecnt; e[++ecnt] = {u, 0, head[v]}; head[v] = ecnt; } }