[NOI2009][BZOJ1565] 植物大战僵尸

1565: [NOI2009]植物大战僵尸

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1654  Solved: 769
[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 。

Source

首先拓扑排序找环,从环上的每个点开始dfs找出所有保护的点,把这些点全都去掉。最后重建图,就是最大权闭合图,跑最大流就好了。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<vector>
  8 #include<set>
  9 #include<queue>
 10 #define INF 100000007
 11 using namespace std;
 12 int sumx,ans,edge,n,m,sum,x,y,num,tot;
 13 int w[666],dis[666],q[666],head[666],head0[666],list[500000],list0[500000],next[500000],next0[500000],key[500000];
 14 int ind[666],topo[666];
 15 bool v[666];
 16 void insert(int x,int y)
 17 {
 18     next[++edge]=head[x];
 19     head[x]=edge;
 20     list[edge]=y;
 21 }
 22 void insert0(int x,int y,int z)
 23 {
 24     next0[++edge]=head0[x];
 25     head0[x]=edge;
 26     list0[edge]=y;
 27     key[edge]=z;
 28 }
 29 int find()
 30 {
 31     for (int i=1;i<=n*m;i++) if (!ind[i]) return i;
 32     return -1;
 33 }
 34 void toposort()
 35 {
 36     for (int i=1;i<=n*m;i++)
 37     {
 38         int k=find();
 39         if (k==-1) break;
 40         topo[++tot]=k;
 41         ind[k]=-1;
 42         for (int j=head[k];j;j=next[j]) ind[list[j]]--;
 43     }
 44 }
 45 void dfs(int x)
 46 {
 47     for (int i=head[x];i;i=next[i])
 48         if (v[list[i]])
 49         {
 50             v[list[i]]=0;
 51             dfs(list[i]);
 52         }
 53 }
 54 void rebuild()
 55 {
 56     edge=1;
 57     for (int i=1;i<=n*m;i++)
 58     {
 59         if (!v[i]) continue;
 60         if (w[i]>0)
 61         {
 62             insert0(0,i,w[i]);
 63             insert0(i,0,0);
 64         }
 65         if (w[i]<0)
 66         {
 67             insert0(i,n*m+1,-w[i]);
 68             insert0(n*m+1,i,0);
 69         }
 70         for (int j=head[i];j;j=next[j])
 71             if (v[list[j]])
 72             {
 73                 insert0(list[j],i,INF);
 74                 insert0(i,list[j],0);
 75             }
 76     }
 77 }
 78 bool BFS()
 79 {
 80     memset(dis,0xff,sizeof(dis));
 81     int x,t=0,w=1;
 82     q[1]=0; dis[0]=1;
 83     while (t<w)
 84     {
 85         x=q[++t];
 86         for (int i=head0[x];i;i=next0[i])
 87             if (key[i]&&dis[list0[i]]==-1)
 88             {
 89                 dis[list0[i]]=dis[x]+1;
 90                 q[++w]=list0[i];
 91             }
 92     }
 93     return dis[n*m+1]!=-1;
 94 }
 95 int find(int x,int flow)
 96 {
 97     if (x==n*m+1) return flow;
 98     int used=0,a;
 99     for (int i=head0[x];i;i=next0[i])
100         if (key[i]&&dis[list0[i]]==dis[x]+1)
101         {
102                                         a=flow-used;
103                                         a=find(list0[i],min(key[i],a));
104                                         key[i]-=a;
105                                         key[i^1]+=a;
106                                         used+=a;
107                                         if (used==flow) return flow;
108         }
109     if (!used) dis[x]=-1;
110     return used;
111 }
112 int main()
113 {
114     memset(v,0,sizeof(v));
115     scanf("%d%d",&n,&m);
116     for (int i=1;i<=n*m;i++)
117     {
118         scanf("%d%d",&w[i],&sum);
119         for (int j=1;j<=sum;j++)
120         {
121             scanf("%d%d",&x,&y);
122             num=x*m+y+1;
123             insert(i,num);
124             ind[num]++;
125         }
126     }
127     for (int i=0;i<n;i++)
128         for (int j=0;j<m-1;j++)
129         {
130             num=i*m+j+1;
131             insert(num+1,num);
132             ind[num]++;
133         }
134     toposort();
135     for (int i=1;i<=tot;i++) v[topo[i]]=1;
136     for (int i=1;i<=n*m;i++)
137         if (!v[i]) dfs(i);
138     for (int i=1;i<=n*m;i++)
139         if (w[i]>0&&v[i]) sumx+=w[i];
140     rebuild();
141     ans=0;
142     while (BFS()) ans+=find(0,INF);
143     printf("%d",sumx-ans);
144     return 0;
145 }
时间: 2024-08-04 16:15:35

[NOI2009][BZOJ1565] 植物大战僵尸的相关文章

bzoj1565【NOI2009】植物大战僵尸

1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 2034  Solved: 944 [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 Samp

【NOI2009】植物大战僵尸

P1589 - [NOI2009]植物大战僵尸 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而 Zombies进攻.该款游戏包含多种不同的挑战系列,比如Protect Your Brain.Bowling等等.其中最为经典的,莫过于玩家通过控制Plants来防守Zombies的进攻,或者相反地由玩家通过控制Zombies 对Plants发起进攻. 现在,我们将要考

[bzoj1565]植物大战僵尸

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

NOI2009植物大战僵尸

这题应该分两步来做: 1.拓扑排序,去掉无敌点 2.求最大闭合子图 需要注意几点: 1.拓扑排序时,如果(i,j)可以攻击到(x,y),那么增加(x,y)的入度,而不是(i,j)的入度 因为入度代表着要攻击它需要事先攻击几个点 2.求最大闭合子图时,用所有的正权点-最大流 3.求最大闭合子图时,如果(i,j)可以攻击到(x,y),那么连一条边(x,y)到(i,j),容量为正无穷 因为在最大闭合子图中边(x,y)到(i,j)意味着选(x,y)就必须要选(i,j),这与实际含义相符 4.s到正权点,

98植物大战僵尸OL_僵尸迷阵

最近在玩植物大战僵尸Ol打到僵尸迷阵,打了个700分倒数第一,擦.....俗话说的好,失败是成功的妈妈,于是花了点时间写了一个小玩意,我相信下次我一定能拿第一 代码非常简单: using UnityEngine; using System.Collections; using UnityEngine.UI; public class MyScript : MonoBehaviour { // Use this for initialization void Start () { } // Upd

植物大战僵尸2天空之城安卓版发布

全体注意!一大波飞行僵尸正在接近中——中国独创版<植物大战僵尸2天空之城>安卓版终于发布了.超乎想象的空战体验.全新僵尸植物军团.独特闪电环境效果和史无前例的战舰成长系统,让你和戴夫共同肩负守卫天空之城的荣耀重任.赶紧下载游戏,加入云端激战吧. <植物大战僵尸2天空之城>安桌版上线 [中国区独有版本 打造铿锵空战体验] <植物大战僵尸2>即将迎来两周年生日,为感谢中国玩家一直以来的热情支持,EA/PopCap携手拓维游戏打造了这款中国区独有新版本<植物大战僵尸2天

原生JS实现的h5小游戏-植物大战僵尸

代码地址如下:http://www.demodashi.com/demo/12755.html 项目介绍 本项目是利用原生js实现的h5小游戏-植物大战僵尸,主要结合了一下自己对于h5小游戏的理解,结合面向对象的编程思想进行开发,在实现时使用了部分es6语法,对于es6语法不太熟悉的小伙伴可以先查阅相关资料了解一下. 如有需要,可根据自己的需求修改源码样式.源码配置属性代码,实现个性化定制. 以下为文件目录结构示意图,核心代码在js文件夹下的四个common.js.main.js.game.js

java小项目之:植物大战僵尸,这个僵尸有点冷!内附素材源码

Java小项目之:植物大战僵尸! <植物大战僵尸>是由PopCap Games开发的一款益智策略类单机游戏,于2009年5月5日发售,这款游戏可谓是无人不知无人不晓. 在我身边,上到40岁的大叔阿姨,下到7.8岁的小弟弟妹妹都听说和玩过这游戏.在以前智能手机还没流行的时候,各种黑网吧,游戏厅便有着玩这游戏的人.当3G技术现世,半智能手机和智能手机出现后,这款游戏更是如日中天,与愤怒的小鸟一起霸占了手机游戏市场(但当时估计都是盗版的). 相信有些使用b站的小伙伴,应该看过很多这样的视频: 这种视

[转]植物大战僵尸95版技术分析

植物大战僵尸95版不是原版,是由植物大战僵尸吧吧友冥谷川恋制作. 本链接只提供95版的完整压缩包和0-95版的所有exe主程序 压缩包,只玩95版的直接下载95安装包解压即可玩,如果需要玩0-94版,再下载本链接提供的主程序exe压缩包,把其它版本的主程序解压到游戏目录直接运行即可.感谢植吧“崇明人家123”制作提供0-v95僵尸得到了极大强化“我会说我这个版本的冒险一周目都过不去吗?”这个出怪模式非常刺激,需要你强大的pvz功底和运气铁桶铁门.显示隐藏关卡.允许后台运行.刺激的出怪模式.无限制