zoukankan      html  css  js  c++  java
  • 【bzoj1565】[NOI2009]植物大战僵尸

    1565: [NOI2009]植物大战僵尸

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 2164  Solved: 1001
    [Submit][Status][Discuss]

    Description

    Input

    Output

    仅包含一个整数,表示可以获得的最大能源收入。注意,你也可以选择不进行任何攻击,这样能源收入为0。

    Sample Input

    3 2
    10 0
    20 0
    -10 0
    -5 1 0 0
    100 1 2 1
    100 0

    Sample Output

    25

    HINT

    在样例中, 植物P1,1可以攻击位置(0,0), P2, 0可以攻击位置(2,1)。 
    一个方案为,首先进攻P1,1, P0,1,此时可以攻击P0,0 。共得到能源收益为(-5)+20+10 = 25。注意, 位置(2,1)被植物P2,0保护,所以无法攻击第2行中的任何植物。 
    【大致数据规模】
    约20%的数据满足1 ≤ N, M ≤ 5;
    约40%的数据满足1 ≤ N, M ≤ 10;
    约100%的数据满足1 ≤ N ≤ 20,1 ≤ M ≤ 30,-10000 ≤ Score ≤ 10000 。

    【题解】

    这题的麻烦之处在于网络中可能出现环,导致死循环。

    首先建图:如果一行之中,有一个植物被在同一行中左边的植物保护,就会形成环,那么我们只需要在每一行的植物向左边一个植物连一条边就行了。然后就是由保护者向被保护者连一条边。

    拓扑判环、删点,不再赘述。

    重新建图:遍历每个点,如果这个点没被删除,就在新图上保留有这个点出发的所有边。并判断:如果点权为正,从此点向终点连边,否则,由起点向此点连边。顺便记下所有正点权之和sum

    求最大流ans后,sum-ans就是答案。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<ctime>
      7 #include<algorithm>
      8 using namespace std;
      9 #define MAXN 610000
     10 #define INF 1000000000
     11 struct node{int y,next,v,rel;}E[MAXN],e[MAXN];
     12 int n,m,len,S,T,ans,sum,v[MAXN],Link1[MAXN],id[MAXN],q[MAXN],del[MAXN],Link[MAXN],level[MAXN];
     13 inline int read()
     14 {
     15     int x=0,f=1;  char ch=getchar();
     16     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
     17     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
     18     return x*f;
     19 }
     20 void insert1(int x,int y)  {id[y]++;E[++len].next=Link1[x];Link1[x]=len;E[len].y=y;}
     21 void insert2(int x,int y,int v)  
     22 {
     23     e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;e[len].rel=len+1;
     24     e[++len].next=Link[y];Link[y]=len;e[len].y=x;e[len].v=0;e[len].rel=len-1;
     25 }
     26 void dfs(int x)
     27 {
     28     del[x]=1;
     29     for(int i=Link1[x];i;i=E[i].next)
     30         if(!del[E[i].y])  dfs(E[i].y);
     31 }
     32 void topsort()
     33 {
     34     int head=0,tail=0;
     35     for(int i=1;i<=n*m;i++)  if(!id[i])  q[++tail]=i;  else del[i]=1;
     36     while(++head<=tail)
     37     {
     38         int now=q[head];
     39         del[now]=0;
     40         for(int i=Link1[now];i;i=E[i].next)
     41         {
     42             id[E[i].y]--;
     43             if(!id[E[i].y])  q[++tail]=E[i].y;
     44         }
     45     }
     46     for(int i=1;i<=n*m;i++)  if(del[i])  dfs(i);
     47 }     
     48 void build()
     49 {
     50     len=0;  S=0;  T=n*m+1;
     51     for(int i=1;i<=n*m;i++)
     52         if(!del[i])
     53         {
     54             if(v[i]>0) {sum+=v[i]; insert2(i,T,v[i]);}
     55             else insert2(S,i,-v[i]);
     56             for(int j=Link1[i];j;j=E[j].next)
     57                 if(!del[E[j].y])
     58                     insert2(i,E[j].y,INF);
     59         }
     60 }
     61 bool bfs()
     62 {
     63     memset(level,-1,sizeof(level));
     64     int head=0,tail=1;
     65     q[1]=S;  level[S]=0;
     66     while(++head<=tail)
     67     {
     68         for(int i=Link[q[head]];i;i=e[i].next)
     69             if(e[i].v&&level[e[i].y]<0)
     70             {
     71                 q[++tail]=e[i].y;
     72                 level[q[tail]]=level[q[head]]+1;
     73             }
     74     }
     75     return level[T]>=0;
     76 }
     77 int MAXFLOW(int x,int flow)
     78 {
     79     if(x==T)  return flow;
     80     int d=0,maxflow=0;
     81     for(int i=Link[x];i&&maxflow<flow;i=e[i].next)
     82         if(level[e[i].y]==level[x]+1&&e[i].v)
     83             if(d=MAXFLOW(e[i].y,min(e[i].v,flow-maxflow)))
     84             {
     85                 maxflow+=d;
     86                 e[i].v-=d;
     87                 e[e[i].rel].v+=d;
     88             }
     89     if(!maxflow)  level[x]=-1;
     90     return maxflow;
     91 }
     92 void solve()
     93 {
     94     int d=0;
     95     while(bfs())
     96         while(d=MAXFLOW(S,INF))
     97             ans+=d;
     98 }
     99 int main()
    100 {
    101     //freopen("pvz.in","r",stdin);
    102     //freopen("pvz.out","w",stdout);
    103     n=read();  m=read();
    104     for(int i=1;i<=n;i++)
    105         for(int j=1;j<=m;j++)
    106         {
    107             int x=(i-1)*m+j;
    108             v[x]=read();  int w=read();
    109             while(w--)
    110             {
    111                 int a=read(),b=read();
    112                 a++;  b++;
    113                 int y=(a-1)*m+b;
    114                 insert1(x,y);
    115             }
    116         }
    117     for(int i=1;i<=n;i++)
    118         for(int j=2;j<=m;j++)
    119         {
    120             int x=(i-1)*m+j,y=x-1;
    121             insert1(x,y);
    122         }
    123     topsort();
    124     build();
    125     solve();
    126     printf("%d
    ",sum-ans);
    127     return 0;
    128 }
  • 相关阅读:
    被.net郁闷的一天
    使用批处理出现奇怪的现象
    我们应该更相信ghost
    asp.net设置默认按钮的一种方法(041217更新)
    asp中access到sql server导入升级后要做的工作。
    一种简单方便的权限控制方案
    为何我的本本不能打开休眠功能?
    祝贺自己的blog开张
    sql server中分页获取数据的存储过程
    httpcompress实际效果能有多少?
  • 原文地址:https://www.cnblogs.com/chty/p/5919790.html
Copyright © 2011-2022 走看看