P1135-Plants vs. Zombies From YTT
Normal (OI)
Total time limit: 10 s memory limit: 128 MB code length limit: 64 kB Background although it has been so many days, although the lonely play many times against plants and zombies ,, I still think it is more fun to write a question than to control botnets. 'description Description: Plants vs. botnets
[Problem description]
Plants Vs. Zombies (PVZ) is a popular little game recently. Plants and zombies are the protagonists of the game, with plants defending and zombies attacking. This game contains a variety of different challenge series, such as protect your brain and bowling. Among them, the most classic is that players defend zombies attacks by controlling plants, or on the contrary, players attack plants by controlling zombies.
Now, we will consider zombies attacking plants in the game. Please note that the rules in this question are different from those in actual games. The game has two types of roles: plants and zombies. Each plant has a set of attack locations that can be protected; zombie attacks plants by going to the position where the plants are located and eating them.
The map of the game can be abstracted as a matrix of N rows of M columns, from top to bottom with 0 to N-1 serial number, column from left to right with 0 to M-1 serial number; there is a plant in each location of the map. For simplicity, we record the plants in Column C of row R as PR and C.
There are many types of plants, including attack, defense, and economics. To briefly describe each plant, the score and attack are defined as follows:
Score [pr, C] zombie breaks down the plant PR, and C can obtain energy. If score [pr, C] is a non-negative integer, it indicates the killing plant PR. C can obtain the energy score [pr, C]. If it is a negative number, it indicates the killing of PR, c requires energy-score [pr, C].
Attack [pr, C] plants PR, C can attack zombie in a set of locations.
Zombies must enter from the right of the map and can only move horizontally. The only way zombies can attack a plant is to go to its location and eat it. Therefore, zombies attacks always start from the right side of the map. That is to say, for the R row of the attack, Zombies must first attack PR, M-1; If You Need To PR, C (0 ≤ C <M-1) attack, must be PR, M-1, PR, m-2... PR, C + 1 first breaks down and moves to the position (R, c) to launch the attack.
In the settings in this question, plants has an infinite attack power. Once zombie enters a certain plant attack location, zombie will be instantly eliminated, and zombie has no time to perform any attack operations. Therefore, even if zombie enters the location where a plant is located, it belongs to the attack location set of other plants, zombie will be instantly destroyed and the plants in the location will be safe (in our settings, the plant attack location does not include its own location, otherwise you will not be able to defeat it ).
Zombies aims to attack plants positions and obtain the largest energy revenue. Each time, you can select an attacking plant for attack. The goal of this question is to develop a zombies attack plan and select which plants to attack and the attack sequence to maximize the energy revenue.
Input Format: inputformat]
The first line of the input file PVZ. In contains two integers, N and M, indicating the number of rows and columns of the map.
The next n × m lines describe the plant information at each location. Line r × m + C + 1 lists the PR and C information of plants in the following format: the first integer is score [pr, C], and the second integer is the set attack [pr, the number of positions in C] is W, and the following W position information (R', C') indicates PR. C can attack the column C in the R' row. Output Format outputformat [output file]
The output file PVZ. Out contains only one integer, indicating the maximum energy revenue. Note that you can also choose not to launch any attacks, so that the energy revenue is 0. Sample input sampleinput [Copy Data]
3 2
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
Sample output sampleoutput [Copy Data]
25
Data range and comment hint [Example]
In this example, plants P1, 1 can attack (0, 0), P2, 0 can attack (2, 1 ).
One solution is to first attack P1, 1, P0, 1, and then attack P0, 0. The total energy gains were (-5) + 20 + 10 = 25. Note that the position (2, 1) is protected by P2 and 0, so it cannot attack any plant in the 2nd rows.
[Approximate data scale]
About 20% of the data can be 1 ≤ n, m ≤ 5;
About 40% of the data must be 1 ≤ n, and m ≤ 10;
About 100% of the data meet the requirements of 1 ≤ n ≤ 20, 1 ≤ m ≤ 30,-10000 ≤ score ≤ 10000 source sourcenoi2009 day2 Problem1
As mentioned in the question solution, this is the largest weighted closed graph. The only note is that the edge table array should be larger as much as possible because of the large number of connected edges. Otherwise, re #9, and try to remove the duplicate edges in the graph. Otherwise, TLE #9.
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;#define MAXN 42#define MAXM 63#define MAXB MAXN*MAXM*4#define MAXV MAXB*4#define MAXE MAXB*1000#define INF 0x3f3f3f3fvector<int> att[MAXB];int score[MAXB];struct Edge{ int np,val; Edge *next,*neg;}E[MAXE],*V[MAXV];int tope=-1;int sour=0,sink=1;void addedge(int x,int y,int z){ //cout<<"ADD:"<<x<<" "<<y<<" "<<z<<endl; E[++tope].np=y; E[tope].val=z; E[tope].next=V[x]; V[x]=&E[tope]; E[++tope].np=x; E[tope].val=0; E[tope].next=V[y]; V[y]=&E[tope]; E[tope].neg=&E[tope-1]; E[tope-1].neg=&E[tope];}int lev[MAXV];int dfs(int now,int maxf){ int ret=0,t; Edge *ne; if(now==sink)return maxf; for (ne=V[now];ne;ne=ne->next) { if (lev[ne->np]!=lev[now]+1 || !ne->val)continue; t=dfs(ne->np,min(maxf,ne->val)); ne->val-=t; ne->neg->val+=t; ret+=t; maxf-=t; } if (!ret) lev[now]=-1; return ret;}int q[MAXV];int vis[MAXV],bfstime=0;bool bfs(){ int head=-1,tail=0; int now; Edge *ne; q[0]=sour; vis[sour]=++bfstime; while (head<tail) { now=q[++head]; for (ne=V[now];ne;ne=ne->next) { if (!ne->val || vis[ne->np]==bfstime)continue; vis[ne->np]=bfstime; lev[ne->np]=lev[now]+1; q[++tail]=ne->np; } } return vis[sink]==bfstime;}int dinic(){ int ret=0; while (bfs()) { ret+=dfs(sour,INF); } return ret;}int low[MAXB],dfn[MAXB];int dfstime=0;int stack[MAXB],tops=-1;bool ok[MAXB];void tarjan(int now){ int i,j; low[now]=dfn[now]=++dfstime; stack[++tops]=now; for (i=0;i<att[now].size();i++) { if (vis[att[now][i]])continue; if (!dfn[att[now][i]]) { tarjan(att[now][i]); low[now]=min(low[now],low[att[now][i]]); }else { low[now]=min(low[now],dfn[att[now][i]]); } } if (low[now]==dfn[now]) { if (stack[tops]==now) { tops--; }else { while (stack[tops]!=now) { ok[stack[tops--]]=false; } ok[stack[tops--]]=false; } } vis[now]=1;}int main(){ freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); int i,j,k,x,y,z,n,m; scanf("%d%d",&n,&m); for (i=0;i<n;i++) { for (j=0;j<m;j++) { scanf("%d%d",&score[i*m+j],&x); for (k=0;k<x;k++) { scanf("%d%d",&y,&z); if (y==i && z<j)continue; att[i*m+j].push_back(y*m+z); } } } for (i=0;i<n;i++) { for (j=0;j<m;j++) { for (k=0;k<j;k++) { att[i*m+j].push_back(i*m+k); } } } int l=n*m; memset(vis,0,sizeof(vis)); memset(ok,1,sizeof(ok)); for (i=0;i<l;i++) { if (!dfn[i]) tarjan(i); } bool flag; for (i=0;i<l;i++) { for (j=0;j<att[i].size();j++) { if (!ok[att[i][j]])continue; addedge(2+att[i][j],2+i,INF); } } int ans=0; for (i=0;i<n;i++) { for (j=m-1;j>=0;j--) { if (!ok[i*m+j])break; if (score[i*m+j]>=0) { addedge(sour,2+i*m+j,score[i*m+j]); ans+=score[i*m+j]; }else { addedge(2+i*m+j,sink,-score[i*m+j]); } } } ans-=dinic(); printf("%d\n",ans); return 0;}
Tyvj p1135-maximum right closure of plants vs. Zombies