BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流
题意:
植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性:
(1)价值;
(2)保护集合,也就是这个植物可以保护矩阵中的某些格子。
现在你是僵尸,你每次只能从(i,m) 格子进入,从右向左进攻。若一个格子是被保护的那么你是不能进入的。每进入一个格子则吃掉该格子的植物并得到其价值(价值有可能是负的),可以中途返回。问可以得到的最大价值是多少?
分析:
这是一道比较真实的题目。(真打游戏的时候应该也是这种景象吧)
首先我们复习一下最大权闭合子图的特质。
有一个有向图,每一个点都有一个权值(可以为正或负或0),选择一个权值和最大的子图,使得每个点的后继都在子图里面,这个子图就叫最大权闭合子图。
上面这句话我们要提炼出一个极其重要的信息:如果我们选择一个点,那就必须选择它的所有后继。
凡是题目中隐含着这样的条件的,我们都可以往最大权闭合子图方向去想一想。
像这道题,每个植物可以保护一些其他的植物。那就意味着,如果我们想要选择一个植物,我们必须首先把所有保护它的植物都选掉。
这样,我们就可以建图,对于一个点x,假如有点y可以保护点x,那么我们就连一条x—>y的边,注意,边的方向和保护的方向是相反的。
(这里有好多题解都不是这么说的,或许另有高论?)
还隐含着一个条件:右边的始终植物保护着左边的植物(对吧?植物大战僵尸里是这样的吧,所以诞生了高坚果)
我们建图,跑最大权闭合子图就好了吗?
并不是……
因为环是无敌的……???!!!
如果在保护关系中出现了环,那么你选任何一个,都是被保护的。
所以我们拓扑,把环的影响取消掉,再跑最大权闭合子图的恶意……
从源点s向每个正权点连一条容量为权值的边,每个负权点向汇点t连一条容量为权值的绝对值的边,有向图原来的边容量全部为无限大答案为正权值之和-最小割
代码:
#include<bits/stdc++.h>
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std;int tot=,n,m,sm=;
const int N=,inf=0x3f3f3f3f;
struct node{int y,z,nxt;}e[N*];
int h[N],c=,q[N],in[N],S,T,d[N],a[N],ans=;
void add(int x,int y,int z){in[x]++;
e[++c]=(node){y,z,h[x]};h[x]=c;
e[++c]=(node){x,,h[y]};h[y]=c;
} bool bfs(){
for(int i=S;i<=T;i++)
if(d[i]!=-) d[i]=-;
int f=,t=;d[S]=;q[++t]=S;
while(f<=t){
int x=q[f++];
for(int i=h[x],y;i;i=e[i].nxt)
if(d[y=e[i].y]==-&&e[i].z)
d[y]=d[x]+,q[++t]=y;
} return (d[T]>);
} int dfs(int x,int f){
if(x==T) return f;int w,tmp=;
for(int i=h[x],y;i;i=e[i].nxt)
if(d[y=e[i].y]==d[x]+&&e[i].z){
w=dfs(y,min(e[i].z,f-tmp));
if(!w) d[y]=-;e[i].z-=w;
e[i^].z+=w;tmp+=w;
if(tmp==f) return f;
} return tmp;
} void solve(){
while(bfs()) tot+=dfs(S,inf);
} int main(){
scanf("%d%d",&n,&m);S=;T=n*m+;
for(int i=,tmp;i<=n*m;i++){
scanf("%d",&a[i]);
a[i]>?add(S,i,a[i]):add(i,T,-a[i]);
scanf("%d",&tmp);while(tmp--){
int x,y;scanf("%d%d",&x,&y);
add(x*m+y+,i,inf);
} if(i%m) add(i,i+,inf);
} int f=,t=;//图是反着建的,拓扑要倒过来
for(int i=S;i<=T;d[i]=-,i++)
if(!in[i]) q[++t]=i;
while(f<=t){
int x=q[f++];d[x]=;
if(a[x]>) sm+=a[x];
for(int i=h[x];i;i=e[i].nxt)
if(i&)if(!--in[e[i].y]) q[++t]=e[i].y;
} solve();
printf("%d\n",sm-tot);return ;
}
最大权闭合子图
BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流的更多相关文章
- BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)
题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...
- bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan
bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...
- BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序
题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...
- P2805 [NOI2009]植物大战僵尸 + 最大权闭合子图 X 拓扑排序
传送门:https://www.luogu.org/problemnew/show/P2805 题意 有一个n * m的地图,你可以操纵僵尸从地图的右边向左边走,走的一些地方是有能量值的,有些地方会被 ...
- BZOJ 1565 植物大战僵尸(拓扑排序+最大权闭合子图)
图中的保护关系就类似于最大权闭合子图.即你想杀x,你就一定要杀掉保护x的点,那么把x向保护它的点连边.那么题目就转化成了最大权闭合子图的问题. 但是这个图有点特殊啊... 考虑有环的情况,显然这个环以 ...
- BZOJ 1565 植物大战僵尸(最大权闭合图)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1565 题意:植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: ...
- codeforces 1082G - Petya and Graph 最大权闭合子图 网络流
题意: 让你选一些边,选边的前提是端点都被选了,求所有的边集中,边权和-点权和最大的一个. 题解: 对于每个边建一个点,然后就是裸的最大权闭合子图, 结果比赛的时候我的板子太丑,一直T,(不会当前弧优 ...
- hiho# 1398 最大权闭合子图 网络流
题目传送门 题意:给出n个活动,m个人,请人需要花费$a[i]$的钱,举办一次活动可以赚$b[i]$的钱,但是需要固定的几个人在场,一个人只需要请一次后就必定在场,问最大收益. 思路: 下列结论来自h ...
- Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序
题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:p ...
随机推荐
- centos 6.2 pptp 客户端 安装(转载)
转自:http://www.lnmpblog.com/archives/611 centos 6.2 64.bit的桌面版本.配置vpn客户端. 步骤: 1.yum -y install pptp 2 ...
- 查询及删除重复记录的SQL语句
1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select * from people where peopleId in (select peopleId from ...
- E20170520-ts
regexp n. 正则表达式 metacharacter メタ文字 元字符 quote vt. 引述,引用; escape v. 逃脱; 逃离; n. 逃走; 逃跑工具或方法; reg ...
- 洛谷P3295 [SCOI2016]萌萌哒(倍增+并查集)
传送门 思路太妙了啊…… 容易才怪想到暴力,把区间内的每一个数字用并查集维护相等,然后设最后总共有$k$个并查集,那么答案就是$9*10^{k-1}$(因为第一位不能为0) 考虑倍增.我们设$f[i] ...
- 用jdbc连接数据库并简单执行SQL语句
一:版本一.这种存在一个问题就是每执行一次操作都会创建一次Connection链接和且释放一次链接 1:创建pojo对象(OR映射,一个pojo类对应一张数据库表) package com.yin ...
- linux下的日志压缩脚本
linux下的日志压缩脚本: #!/bin/bash #第一步:先定义项目列表如下: projects="project-a project-b project-c project-d&qu ...
- _bzoj1087 [SCOI2005]互不侵犯King【dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1087 令f(i, j, k)表示前i列,二进制状态为j,已经用了k个国王的方案数,则 f(i ...
- bryce1010专题训练——线段树习题汇总
一.区间查询,无单点更新 hdu2795 Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 ...
- 洛谷 P2061 [USACO07OPEN]城市的地平线City Horizon
简化版的矩形面积并,不用线段树,不用离散化,代码意外的简单 扫描线,这里的基本思路就是把要求的图形竖着切几刀分成许多矩形,求面积并.(切法就是每出现一条与y轴平行的线段都切一刀) 对于每一个切出来的矩 ...
- A Simple Task CodeForces - 11D
A Simple Task CodeForces - 11D 题意:输出一个无向图的简单环数量.简单环指无重复边的环.保证图无重边自环. ans[i][j]表示"包含i中的点,以i中第一个点 ...