http://www.lydsy.com/JudgeOnline/problem.php?id=1565
https://www.byvoid.com/blog/noi-2009-pvz
拓扑排序 + 最大权闭合子图。
const int N = 600 + 3, M = N * N * 4; struct Network_Flow{ int D[N], hd[N], suc[M], to[M], cap[M]; int n, m, s, t; inline void ae(int x, int y, int c){ suc[m] = hd[x], hd[x] = m, to[m] = y, cap[m++] = c, suc[m] = hd[y], hd[y] = m, to[m] = x, cap[m++] = 0; } inline void aee(int x, int y, int c){ suc[m] = hd[x], hd[x] = m, to[m] = y, cap[m++] = c, suc[m] = hd[y], hd[y] = m, to[m] = x, cap[m++] = c; } #define v to[i] #define c cap[i] #define f cap[i^1] LL sap(){ LL z=0; static int cnt[N],cur[N],pre[N]; fill(D,D+n,n),fill(cnt,cnt+n,0);cnt[n]=n; int u=s;cur[s]=hd[s];while (D[s]){ #define i cur[u] if (u==t){ int d=INF;for(u=s;u!=t;u=v)checkMin(d,c); z+=d;for(u=s;u!=t;u=v)f+=d,c-=d;u=s; } #undef i int i;for(i=cur[u];i;i=suc[i]){ if(D[u]+1==D[v]&&c){cur[u]=i,cur[v]=hd[v],pre[v]=u,u=v;break;} } if (!i){ if (!--cnt[D[u]])break; D[u]=1;REP_G(i,u)if(c)checkMax(D[u],D[v]);--D[u]; ++cnt[D[u]];if(u==s)cur[u]=hd[u];else u=pre[u]; } } return z; } void init(int _n){ n = _n; s = 0, t = n + 1; m = 2; n = t + 1; fill(hd, hd+n, 0); } } G; #undef v #undef c #undef f VI _adj[N], adj[N]; int inD[N], scr[N], h[N], q[N] = {M}, op, cz, u, v; int r, c, s, t, n, m, ans; inline void add_edge(int x, int y){ ++inD[y], _adj[x].PB(y); } inline int id(int x, int y){ return x * c + y + 1; } #define v _adj[u][i] void init(){ RD(r, c); REP(i, r) REP(j, c){ if (j != 0) add_edge(id(i, j), id(i, j-1)); int t, x, y; RDD(scr[id(i, j)]); Rush RD(x, y), add_edge(id(i, j), id(x, y)); } n = r * c; // Toposort .. op = 0; REP_1(i, n) if (!inD[i]) q[++op] = i; while (op){ u = q[op--]; REP(i, SZ(_adj[u])){ --inD[v]; if (!inD[v]) q[++op] = v; } } // Graph Initializing.. G.init(n); REP_1(u, n) if (!inD[u]){ if (scr[u] > 0){ G.ae(G.s, u, scr[u]); ans += scr[u]; } else G.ae(u, G.t, -scr[u]); REP(i, SZ(_adj[u])){ if (!inD[v]) G.ae(v, u, INF); } } } #undef v int main(){ #ifndef ONLINE_JUDGE freopen("/users/xiaodao/desktop/Exercise/in.txt", "r", stdin); //freopen("/users/xiaodao/desktop/Exercise/out.txt", "w", stdout); #endif init(); printf("%d\n", ans - G.sap()); }