1565: [NOI2009] Plants vs Zombies time limit:10 Sec Memory limit:64 MB
submit:1972 solved:917
[Submit] [Status] [Discuss] The descriptioninputoutput contains only an integer that represents the maximum energy income that can be obtained. Note that you can also choose not to do any attacks so that the energy income is 0. Sample Input3 2
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
Sample Output25
HINT
In the sample, the plant p1,1 can attack position (0,0), P2, 0 can attack position (2,1).
A scheme for, first attack p1,1, p0,1, at this time can attack p0,0. The total energy gain is (-5) +20+10 = 25. Note that the location (2,1) is protected by plant p2,0, so it is not possible to attack any plant in line 2nd.
"Approximate data size"
About 20% of the data meet 1≤n, m≤5;
About 40% of the data meet 1≤n, m≤10;
About 100% of the data meets 1≤n≤20,1≤m≤30,-10000≤score≤10000.
SourceSolution
The first thought was that adding restrictions to the grid and then doing it, found that it was not true, because the plants and grids that could be eaten had nothing to do with the plant's attacks.
It is easy to think that if a plant is protected by another plant, it must be eaten by another plant to eat the plant, so it is clear that the order is to be considered, but it is also found that if multiple plants can protect each other (that is, even ring, it is obvious that these plants are invincible RMB players)
This type is easy to associate with the minimum cut model (maximum weight closure), and because the ring on the plant invincible, so do not consider the ring on the plant, then the ring on the throw away can
began to want to write Tarjan, after writing found no, so change topological sort, and then found too long has not written, unexpectedly quickly forget ....
Here can be directly built network flow diagram, topology once, in the augmented when the limit can be added. (But some special tricks are needed)
or first to protect the point of the edge, topology again, and then build a new diagram to run the network stream can be noted: the point of protection to add it to the left of the point (it is clear that zombies can not skip a plant to eat the back)
Code
#include <iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<queue>#include<stack>using namespacestd;intRead () {intx=0, f=1;CharCh=GetChar (); while(ch<'0'|| Ch>'9') {if(ch=='-') f=-1; Ch=GetChar ();} while(ch>='0'&& ch<='9') {x=x*Ten+ch-'0'; Ch=GetChar ();} returnx*F;}#defineMAXN 1000#defineMAXM 1000010intN,M,TOTAL,SCORE[MAXN];structedgenode{intNext,to,cap;} EDGE[MAXM];intHead[maxn],cnt=1;voidAddedge (intUintVintW) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=W;}voidInsertedge (intUintVintW) {Addedge (u,v,w); Addedge (V,u,0);}structroadnode{intNext,to;} Road[maxm>>1];intLast[maxn],tot;voidAddroad (intUintV) {tot++; road[tot].next=last[u]; last[u]=tot; road[tot].to=v;}voidInsertroad (intUintv) {addroad (u,v);}BOOLVISIT[MAXN];intdu[maxn],s,t;voidPaint (intNow ) {Visit[now]=1; for(intI=last[now]; I I=road[i].next)if(!Visit[road[i].to]) Paint (road[i].to);}voidToposort () {s=1, t=n*m; Stack<int>St; for(intI=s; i<=t; i++)if(!du[i]) St.push (i);Elsevisit[i]=1; while(!St.empty ()) { intNow=st.top (); St.pop (); visit[now]=0; for(intI=last[now]; I I=Road[i].next) {Du[road[i].to]--; if(!du[road[i].to]) St.push (road[i].to); } //printf ("%d\n", now); } for(intk=1; i<=t; i++)if(Visit[i]) Paint (i);}intdis[maxn],cur[maxn],s,t;#defineINF 0x7fffffffBOOLBFs () {Queue<int>Q; for(intI=s; i<=t; i++) dis[i]=-1; Q.push (S); Dis[s]=0; while(!Q.empty ()) { intnow=Q.front (); Q.pop (); for(intI=head[now]; I I=edge[i].next)if(Edge[i].cap && dis[edge[i].to]==-1) dis[edge[i].to]=dis[now]+1, Q.push (edge[i].to); } returndis[t]!=-1;}intDfsintLocintLow ) { if(loc==t)returnLow ; intW,used=0; for(intI=cur[loc]; I I=edge[i].next)if(Edge[i].cap && dis[edge[i].to]==dis[loc]+1) {W=dfs (Edge[i].to,min (low-used,edge[i].cap)); Edge[i].cap-=w; edge[i^1].cap+=w; used+=W; if(Used==low)returnLowif(EDGE[I].CAP) cur[loc]=i; } if(!used) dis[loc]=-1; returnused;}intDinic () {inttmp=0; while(BFS ()) { for(intI=s; i<=t; i++) cur[i]=Head[i]; TMP+=DFS (S,inf); } returntmp;}voidBuild () {S=0, t=n*m+1; for(intI=1; i<=n*m; i++) if(!Visit[i]) { if(score[i]>0) Insertedge (I,t,score[i]);ElseInsertedge (s,i,-Score[i]); for(intJ=last[i]; J j=road[j].next)if(!visit[road[j].to]) Insertedge (I,road[j].to,inf); Total+=score[i]>0? Score[i]:0; }}intLocateintXintY) {return(X-1) *m+y;}intMain () {n=read (), m=read (); for(intI=1; i<=n; i++) for(intj=1; j<=m; J + +) { intnow=Locate (i,j), Num; Score[now]=read (); num=read (); for(intx,y,k=1; k<=num; k++) x=read () +1, Y=read () +1, Insertroad (Now,locate (x, y)), du[locate (x, y)]++; if(j>1) Insertroad (Now,locate (i,j-1)), Du[locate (i,j-1)]++; } toposort (); Build (); intMaxflow=dinic ();//printf ("%d%d\n", total,maxflow);printf"%d\n", total-Maxflow); return 0;}
Write this need to re-composition, with the road Ah Last,tot ah what, will always be confused to write mixed ... and wasting time with the naked eye.
"BZOJ-1565" Plants vs Zombies topology sort + min cut