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就是答案。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<algorithm>
using namespace std;
#define MAXN 610000
#define INF 1000000000
struct node{int y,next,v,rel;}E[MAXN],e[MAXN];
int n,m,len,S,T,ans,sum,v[MAXN],Link1[MAXN],id[MAXN],q[MAXN],del[MAXN],Link[MAXN],level[MAXN];
inline int read()
{
int x=,f=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-; ch=getchar();}
while(isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
void insert1(int x,int y) {id[y]++;E[++len].next=Link1[x];Link1[x]=len;E[len].y=y;}
void insert2(int x,int y,int v)
{
e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;e[len].rel=len+;
e[++len].next=Link[y];Link[y]=len;e[len].y=x;e[len].v=;e[len].rel=len-;
}
void dfs(int x)
{
del[x]=;
for(int i=Link1[x];i;i=E[i].next)
if(!del[E[i].y]) dfs(E[i].y);
}
void topsort()
{
int head=,tail=;
for(int i=;i<=n*m;i++) if(!id[i]) q[++tail]=i; else del[i]=;
while(++head<=tail)
{
int now=q[head];
del[now]=;
for(int i=Link1[now];i;i=E[i].next)
{
id[E[i].y]--;
if(!id[E[i].y]) q[++tail]=E[i].y;
}
}
for(int i=;i<=n*m;i++) if(del[i]) dfs(i);
}
void build()
{
len=; S=; T=n*m+;
for(int i=;i<=n*m;i++)
if(!del[i])
{
if(v[i]>) {sum+=v[i]; insert2(i,T,v[i]);}
else insert2(S,i,-v[i]);
for(int j=Link1[i];j;j=E[j].next)
if(!del[E[j].y])
insert2(i,E[j].y,INF);
}
}
bool bfs()
{
memset(level,-,sizeof(level));
int head=,tail=;
q[]=S; level[S]=;
while(++head<=tail)
{
for(int i=Link[q[head]];i;i=e[i].next)
if(e[i].v&&level[e[i].y]<)
{
q[++tail]=e[i].y;
level[q[tail]]=level[q[head]]+;
}
}
return level[T]>=;
}
int MAXFLOW(int x,int flow)
{
if(x==T) return flow;
int d=,maxflow=;
for(int i=Link[x];i&&maxflow<flow;i=e[i].next)
if(level[e[i].y]==level[x]+&&e[i].v)
if(d=MAXFLOW(e[i].y,min(e[i].v,flow-maxflow)))
{
maxflow+=d;
e[i].v-=d;
e[e[i].rel].v+=d;
}
if(!maxflow) level[x]=-;
return maxflow;
}
void solve()
{
int d=;
while(bfs())
while(d=MAXFLOW(S,INF))
ans+=d;
}
int main()
{
//freopen("pvz.in","r",stdin);
//freopen("pvz.out","w",stdout);
n=read(); m=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
int x=(i-)*m+j;
v[x]=read(); int w=read();
while(w--)
{
int a=read(),b=read();
a++; b++;
int y=(a-)*m+b;
insert1(x,y);
}
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
int x=(i-)*m+j,y=x-;
insert1(x,y);
}
topsort();
build();
solve();
printf("%d\n",sum-ans);
return ;
}

【bzoj1565】[NOI2009]植物大战僵尸的更多相关文章

  1. 【最大权闭合子图 tarjan】bzoj1565: [NOI2009]植物大战僵尸

    dinic+tarjan板子练手题 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其 中P ...

  2. BZOJ1565: [NOI2009]植物大战僵尸

    Description Input Output 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. Sample Input 3 2 10 0 20 0 ...

  3. BZOJ1565——[NOI2009]植物大战僵尸

    1.题意:有一些点,点与点之间有保护关系,每个点都有一个权值,求能获得的最大值 2.分析:裸的最大权闭合图,用网络流进行求解,然后我们发现点与点之间的保护关系可能构成环,这样网络流是无法处理的,然后我 ...

  4. 【bzoj1565】 NOI2009—植物大战僵尸

    http://www.lydsy.com/JudgeOnline/problem.php?id=1565 (题目链接) 题意 给出$n*m$的棋盘,僵尸攻击每个格子可以获得$v$的分数,每个格子又会保 ...

  5. 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  6. P2805 [NOI2009]植物大战僵尸

    题目地址:P2805 [NOI2009]植物大战僵尸 最大权闭合子图 若有向图 \(G\) 的子图 \(V\) 满足: \(V\) 中顶点的所有出边均指向 \(V\) 内部的顶点,则称 \(V\) 是 ...

  7. COGS410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  8. BZOJ 1565: [NOI2009]植物大战僵尸

    1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2317  Solved: 1071[Submit][Stat ...

  9. 【刷题】BZOJ 1565 [NOI2009]植物大战僵尸

    Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻. ...

随机推荐

  1. canvas实现点击带水纹的按钮

    咱今天在闲逛网页时,看到一个点击带水纹的按钮特效,尼玛,写的还挺好,先看效果: 于是就奔着升级版的拿来主义,别人的好东西,咱都要拿来滴,so,扒代码! 完整代码在最后,是经过我的改进优化滴. 在这里先 ...

  2. ASP调用存储过程访问SQL Server

     ASP调用存储过程访问SQL Server 2011-02-15 10:22:57 标签:asp 数据库 sQL 存储过程 Server ASP和存储过程(Stored Procedures)的文章 ...

  3. Ubuntu命令:sudo、shutdown、apt-get、vim

    切换成ROOT用户: Ubuntu中默认不开启root账户,所以root账户是没有密码的, 但是会有一个非root的管理员账户,可以通过sudo来获得root权限,现在就可以用这个账户来设置密码 ** ...

  4. Redis设计与实现 (二): 链表

    Redis实现为双链表结构, 列表键的底层实现之一就是链表,  发布与订阅, 慢查询, 监视器等功能都用到了链表. Redis本身也使用链表维持多个客户端. 节点定义, 位于 adlist.h/lis ...

  5. 重温CLR(六)方法和参数

    实例构造器和类(引用类型) 构造器是将类型的实例初始化为良好状态的特殊方法.构造器方法在“方法定义元数据表”中始终叫做.ctor(constructor的简称).创建引用类型的实例时,首先为实例的数据 ...

  6. Vue.js devtool插件下载安装及后续问题解决

    在中国,你是无法使用谷歌应用商店,所以你下载插件,要使用一些别的手段,一种是下载源码编译,另一种是通过第三方网站.第一种不适合小白,所以现在介绍第二组. 下载插件网站 国外网站:https://www ...

  7. 数据库模型类转换实体类的dbToPojoUtil工具类开发

    idea颜色说明http://blog.csdn.net/saindy5828/article/details/53319693 1,中途运用了properties,properties.getPro ...

  8. 如何用php+ajax实现页面的局部刷新?(转)

    client.html XML/HTML code   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!DOCTYPE ...

  9. Ubuntu14.04安装搜狗输入法的一点小问题

    难得搜狗输入法支持ubuntu,果断下载尝试一把. 官网:http://pinyin.sogou.com/linux/ 官网教程:http://pinyin.sogou.com/linux/help. ...

  10. 蓝桥杯 算法训练 ALGO-108 最大的体积

    算法训练 最大体积   时间限制:1.0s   内存限制:256.0MB 问题描述 每个物品有一定的体积(废话),不同的物品组合,装入背包会战用一定的总体积.假如每个物品有无限件可用,那么有些体积是永 ...