zoukankan      html  css  js  c++  java
  • bzoj 1565(ACM恢复训练)

    1565: [NOI2009]植物大战僵尸

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 3254  Solved: 1508
    [Submit][Status][Discuss]

    Description

    Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏。Plants(植物)和Zombies(僵尸)是游戏的主角,其
    中Plants防守,而Zombies进攻。该款游戏包含多种不同的挑战系列,比如Protect Your Brain、Bowling等等。其
    中最为经典的,莫过于玩家通过控制Plants来防守Zombies的进攻,或者相反地由玩家通过控制Zombies对Plants发
    起进攻。
     
    现在,我们将要考虑的问题是游戏中Zombies对Plants的进攻,请注意,本题中规则与实际游戏有所不同。游戏中
    有两种角色,Plants和Zombies,每个Plant有一个攻击位置集合,它可以对这些位置进行保护;而Zombie进攻植物
    的方式是走到植物所在的位置上并将其吃掉。
     
    游戏的地图可以抽象为一个N行M列的矩阵,行从上到下用0到N–1编号,列从左到右用0到M–1编号;在地图的每个
    位置上都放有一个Plant,为简单起见,我们把位于第r行第c列的植物记为Pr, c。
     
    Plants分很多种,有攻击类、防守类和经济类等等。为了简单的描述每个Plant,定义Score和Attack如下:
     
    Score[Pr, c]
     
    Zombie击溃植物Pr, c可获得的能源。若Score[Pr, c]为非负整数,则表示击溃植物Pr, c可获得能源Score[Pr, c]
    ,若为负数表示击溃Pr, c需要付出能源 -Score[Pr, c]。
     
    Attack[Pr, c]
     
    植物Pr, c能够对Zombie进行攻击的位置集合。
     
    Zombies必须从地图的右侧进入,且只能沿着水平方向进行移动。Zombies攻击植物的唯一方式就是走到该植物所在
    的位置并将植物吃掉。因此Zombies的进攻总是从地图的右侧开始。也就是说,对于第r行的进攻,Zombies必须首
    先攻击Pr, M-1;若需要对Pr, c(0 ≤ c < M-1)攻击,必须将Pr,M-1, Pr, M-2 … Pr, c+1先击溃,并移动到位
    置(r, c)才可进行攻击。
     
    在本题的设定中,Plants的攻击力是无穷大的,一旦Zombie进入某个Plant的攻击位置,该Zombie会被瞬间消灭,
    而该Zombie没有时间进行任何攻击操作。因此,即便Zombie进入了一个Plant所在的位置,但该位置属于其他植物
    的攻击位置集合,则Zombie会被瞬间消灭而所在位置的植物则安然无恙(在我们的设定中,Plant的攻击位置不包
    含自身所在位置,否则你就不可能击溃它了)。
     
    Zombies的目标是对Plants的阵地发起进攻并获得最大的能源收入。每一次,你可以选择一个可进攻的植物进行攻
    击。本题的目标为,制定一套Zombies的进攻方案,选择进攻哪些植物以及进攻的顺序,从而获得最大的能源收入

    Input

    第一行包含两个整数N, M,分别表示地图的行数和列数。
    接下来N×M行描述每个位置上植物的信息。第r×M + c + 1行按照如下格式给出植物Pr, c的信息:
    第一个整数为Score[Pr, c], 第二个整数为集合Attack[Pr, c]中的位置个数w,
    接下来w个位置信息(r’, c’),表示Pr, c可以攻击位置第r’ 行第c’ 列。
    1 ≤ N ≤ 20,1 ≤ M ≤ 30,-10000 ≤ Score ≤ 10000 。
     
     

    Output

    仅包含一个整数,表示可以获得的最大能源收入。
    注意,你也可以选择不进行任何攻击,这样能源收入为0。
     
    先tarjian,再跑最大权闭合子图。用topo序连边建图,标记不能被选的点。
    第二份代码迷之WA。待调
      1 /**************************************************************
      2     Problem: 1565
      3     User: zqq
      4     Language: C++
      5     Result: Accepted
      6     Time:236 ms
      7     Memory:64028 kb
      8 ****************************************************************/
      9  
     10 #include<iostream>
     11 #include<cstdio>
     12 #include<cstring>
     13 #include<algorithm>
     14 using namespace std;
     15 #define maxn 2020
     16 #define maxm 2000020
     17 #define inf 0x3f3f3f3f
     18 struct node1{
     19     int to,next;
     20 }e1[maxm];
     21 struct node2{
     22     int to,next,f;
     23 }e2[maxm * 2];
     24 int head1[maxn],head2[maxn],cnt1,cur[maxn],cnt2 = 1,dfn[maxn],low[maxn],dfstime,belong[maxn],size[maxn];
     25 int stack[maxn],tops = -1,ins[maxn];
     26 int n,m,val[maxn],tot,src,sink,mincut,sum,dis[maxn],cant[maxn];
     27 int q[maxn * 20],hh,tt;
     28  
     29 inline void adde1(int x,int y){
     30     e1[++cnt1].to = y;
     31     e1[cnt1].next = head1[x];
     32     head1[x] = cnt1;
     33 }
     34 void tarjian(int now){
     35     dfn[now] = low[now] = ++dfstime;
     36     if ( !ins[now] ) stack[++tops] = now , ins[now] = 1;
     37     for (int i = head1[now] ; i ; i = e1[i].next){
     38         if ( !dfn[e1[i].to]  ){
     39             tarjian(e1[i].to) , low[now] = min(low[now],low[e1[i].to]);
     40         }
     41         if ( ins[e1[i].to] ){
     42             low[now] = min(low[now],dfn[e1[i].to]);
     43         }
     44     }
     45     if ( dfn[now] == low[now] ){
     46         int x = stack[tops--];
     47         while ( x != now ){
     48             ins[x] = 0;
     49             size[now]++;
     50             belong[x] = now;
     51             x = stack[tops--];
     52         }
     53         belong[now] = now , ins[now] = 0 , size[now]++;
     54     }
     55 }
     56 inline void bfs2(){
     57     hh = tt = 0;
     58     for (int i = 1 ; i <= n * m ; i++)
     59         if ( belong[i] == i && size[i] > 1 ) q[tt++] = i , cant[i] = 1;
     60     while ( hh < tt ){
     61         int now = q[hh++];
     62         for (int i = head1[now] ; i ; i = e1[i].next){
     63             if ( !cant[e1[i].to] ){
     64                 cant[e1[i].to] = 1;
     65                 q[tt++] = e1[i].to;
     66             }   
     67         }   
     68     }
     69 }
     70 inline void adde2(int x,int y,int c){
     71     e2[++cnt2].to = y;
     72     e2[cnt2].next = head2[x];
     73     e2[cnt2].f = c;
     74     head2[x] = cnt2;
     75     e2[++cnt2].to = x;
     76     e2[cnt2].next = head2[y];
     77     e2[cnt2].f = 0;
     78     head2[y] = cnt2;
     79 }
     80 inline bool bfs(){
     81     memset(dis,0,sizeof(dis));
     82     hh = tt = 0;
     83     q[tt++] = src;
     84     dis[src] = 1;
     85     while ( hh < tt ){
     86         int now = q[hh++];
     87         for (int i = head2[now] ; i ; i = e2[i].next){
     88             if ( e2[i].f && !dis[e2[i].to] ){
     89                 dis[e2[i].to] = dis[now] + 1;
     90                 q[tt++] = e2[i].to;
     91             }
     92         }
     93     }
     94     return dis[sink] > 0;
     95 }
     96 int dfs(int now,int delta){
     97     if ( now == sink ) return delta;
     98     else{
     99         int ret = 0;
    100         for (int &i = cur[now] ; i && delta ; i = e2[i].next){
    101             if ( e2[i].f && dis[now] + 1 == dis[e2[i].to] ){
    102                 int dd = dfs(e2[i].to,min(delta,e2[i].f));
    103                 ret += dd;
    104                 delta -= dd;
    105                 e2[i].f -= dd;
    106                 e2[i ^ 1].f += dd;
    107                 if ( !delta ) return ret;
    108             }
    109         }
    110         if ( delta ) dis[now] = -1;
    111         return ret;
    112     }
    113 }
    114 int main(){
    115     scanf("%d %d",&n,&m);
    116     for (int i = 1 ; i <= n * m ; i++){
    117         int w;
    118         scanf("%d %d",&val[i],&w);
    119         for (int j = 1 ; j <= w ; j++){
    120             int r,c;
    121             scanf("%d %d",&r,&c);
    122             adde1(i,r * m + c + 1);
    123         }
    124     }
    125     for (int i = 1 ; i <= n ; i++){
    126         for (int j = 2 ; j <= m ; j++){
    127             adde1((i - 1) * m + j,(i - 1) * m + j - 1);
    128         }
    129     }
    130     for (int i = 1 ; i <= n * m ; i++){
    131         if ( !dfn[i] ) 
    132             tarjian(i);
    133     }
    134     bfs2();
    135 //  for (int i = 1 ; i <= n * m ; i++) cout<<cant[i]<<" ";
    136 //  cout<<endl;
    137     for (int i = 1 ; i <= n * m ; i++){
    138         if ( !cant[i] ){
    139             ++tot;
    140             if ( val[i] > 0 ) sum += val[i];
    141         }
    142     }
    143     src = n * m + 1 , sink = n * m + 2;
    144     for (int i = 1 ; i <= n * m ; i++){
    145         for (int j = head1[i] ; j ; j = e1[j].next){
    146             if ( belong[e1[j].to] != belong[i] && !cant[belong[i]] && !cant[belong[e1[j].to]]  ){
    147                 adde2(belong[e1[j].to],belong[i],inf);
    148             }
    149         }
    150     }
    151     for (int i = 1 ; i <= n * m ; i++){
    152         if ( !cant[i] ){
    153             if ( val[i] > 0 ) adde2(src,i,val[i]);
    154             if ( val[i] < 0 ) adde2(i,sink,-val[i]);
    155         }
    156     }
    157     while ( bfs() ){
    158         for (int i = 1 ; i <= sink ; i++) cur[i] = head2[i];
    159         mincut += dfs(src,inf);
    160     }
    161     //1cout<<sum<<" "<<mincut<<endl;
    162     printf("%d",sum - mincut);
    163     return 0;
    164 }
    View Code
      1 /**************************************************************
      2     Problem: 1565
      3     User: zqq
      4     Language: C++
      5     Result: Wrong_Answer
      6 ****************************************************************/
      7  
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<algorithm>
     12 using namespace std;
     13 #define maxn 1020
     14 #define maxm 2000020
     15 #define inf 0x3f3f3f3f
     16  
     17 struct node{
     18     int next,to,f;
     19 }e2[maxn],e[maxm * 2];
     20 int head[maxn],cur[maxn],head2[maxn],cnt = 1;
     21 int n,m,ans,v[maxn];
     22 int dfn[maxn],low[maxn],stack_[maxn],tops,ins[maxn],dfstime,sz[maxn],belong[maxn],vis[maxn],deg[maxn],can[maxn];
     23 int q[maxn],tt,hh,dis[maxn],S,T;
     24  
     25 inline void adde(int x,int y){
     26     e[++cnt].to = y;
     27     e[cnt].next = head[x];
     28     head[x] = cnt;
     29 }
     30 inline void adde(int x,int y,int f){
     31     e[++cnt].to = y;
     32     e[cnt].next = head[x];
     33     e[cnt].f = f;
     34     head[x] = cnt;
     35     e[++cnt].to = x;
     36     e[cnt].next = head[y];
     37     head[y] = cnt;
     38 }   
     39 inline void adde2(int x,int y){
     40     e2[++cnt].to = y;
     41     e2[cnt].next = head2[x];
     42     head2[x] = cnt;
     43 }
     44 void dfs(int x){
     45     dfn[x] = low[x] = ++dfstime;
     46     if ( !ins[x] ) stack_[++tops] = x , ins[x] = 1;
     47     for (int i = head[x] ; i ; i = e[i].next){
     48         int to = e[i].to;
     49         if ( !dfn[to] ) dfs(to) , low[x] = min(low[x],low[to]);
     50         else if ( ins[to] ) low[x] = min(low[x],low[to]);
     51     }
     52     if ( low[x] == dfn[x] ){
     53         int now = stack_[tops--];
     54         while ( now != x ){
     55             sz[x]++ , belong[now] = x , ins[now] = 0;
     56             now = stack_[tops--];
     57         }
     58         sz[x]++ , belong[x] = x , ins[x] = 0;
     59     }
     60 }
     61  
     62 void topo(){
     63     for (int i = 1 ; i <= n * m ; i++){
     64         if ( sz[i] == 1 ) can[i] = 1;
     65         if ( !deg[i] && belong[i] == i ) q[tt++] = i;
     66     }
     67     while ( hh < tt ){
     68         int x = q[hh++];
     69         for (int i = head2[x] ; i ; i = e2[i].next){
     70             int to = e2[i].to;
     71             deg[to]--;
     72             if ( !can[x] ) can[to] = 0;
     73             if ( !deg[to] ) q[tt++] = to;
     74         }
     75     }
     76 }
     77 void dfs2(int x){
     78     if ( vis[x] || !can[x] ) return;
     79     vis[x] = 1;
     80     if ( v[x] > 0 ) ans += v[x] , adde(S,x,v[x]);
     81     else if ( v[x] < 0 ) adde(x,T,-v[x]);
     82     for (int i = head2[x] ; i ; i = e2[i].next){
     83         adde(e2[i].to,x,inf);
     84         dfs2(e2[i].to);
     85     }
     86 }
     87  
     88 void init(){
     89     S = n * m + 1 , T = S + 1 , cnt = 0;
     90     for (int i = 1 ; i <= n * m ; i++) 
     91         for (int j = head[i] ; j ; j = e[j].next)
     92             if ( belong[i] != belong[e[j].to] ) 
     93                 adde2(belong[i],belong[e[j].to]) , deg[belong[e[j].to]]++;
     94     topo();
     95     cnt = 1 , memset(head,0,sizeof(head)) , memset(e,0,sizeof(e));
     96     for (int i = 0 ; i < tt ; i++) if ( !vis[q[i]] ) dfs2(q[i]);
     97 }
     98 bool bfs(){
     99     memset(dis,0,sizeof(dis));
    100     tt = hh = 0;
    101     q[tt++] = S , dis[S] = 1;
    102     while ( hh < tt ){
    103         int x = q[hh++];
    104         for (int i = head[x] ; i ; i = e[i].next){
    105             if ( e[i].f && !dis[e[i].to] ){
    106                 dis[e[i].to] = dis[x] + 1;
    107                 q[tt++] = e[i].to;
    108             }
    109         }
    110     }
    111     return dis[T];
    112 }
    113 int dfs2(int x,int delta){
    114     if ( x == T || !delta ) return delta;
    115     int res = 0;
    116     for (int &i = cur[x] ; i ; i = e[i].next){
    117         if ( e[i].f && dis[e[i].to] == dis[x] + 1 ){
    118             int d = dfs2(e[i].to,min(e[i].f,delta));
    119             e[i].f -= d , e[i ^ 1].f += d;
    120             delta -= d , res += d;
    121             if ( !delta ) return res;
    122         }
    123     }
    124     if ( delta ) dis[x] = -1;
    125     return res;
    126 }   
    127 int main(){
    128     scanf("%d %d",&n,&m);
    129     for (int i = 1 ; i <= n ; i++) for (int j = 1 ; j <= m ; j++){
    130         int w,d,x,y;
    131         scanf("%d %d",&d,&w);
    132         v[(i - 1) * m + j] = d;
    133         for (int k = 1 ; k <= w ; k++){
    134             scanf("%d %d",&x,&y) , x++ , y++;
    135             adde((i - 1) * m + j,(x - 1) * m + y);
    136         }
    137         if ( j > 1 ) adde((i - 1) * m + j,(i - 1) * m + j - 1);
    138     }
    139     for (int i = 1 ; i <= n * m ; i++) 
    140         if ( !dfn[i] ) dfs(i);
    141     init();
    142     while ( bfs() ){
    143         memcpy(cur,head,sizeof(head));
    144         ans -= dfs2(S,inf);
    145     }
    146     printf("%d
    ",ans);
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    keil编译器从ac5迁移到ac6
    分享一个简单易用的软件定时器模块(MultiTimer)——基于keil+stm32f103zet+hal库(裸机实现)
    PID动图——很形象
    jlink之j-scope使用
    Keil的RTX特性
    Keil5创建基于RTX的STM32工程(转载+自己的体会)
    CMSIS-RTOS 简介
    Chapter 3 Phenomenon——13
    Chapter 3 Phenomenon——12
    Chapter 3 Phenomenon——11
  • 原文地址:https://www.cnblogs.com/zqq123/p/9242807.html
Copyright © 2011-2022 走看看