题意:

  植物大战僵尸,一个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 植物大战僵尸 最大权闭合子图+网络流的更多相关文章

  1. BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)

    题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...

  2. bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan

    bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...

  3. BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序

    题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...

  4. P2805 [NOI2009]植物大战僵尸 + 最大权闭合子图 X 拓扑排序

    传送门:https://www.luogu.org/problemnew/show/P2805 题意 有一个n * m的地图,你可以操纵僵尸从地图的右边向左边走,走的一些地方是有能量值的,有些地方会被 ...

  5. BZOJ 1565 植物大战僵尸(拓扑排序+最大权闭合子图)

    图中的保护关系就类似于最大权闭合子图.即你想杀x,你就一定要杀掉保护x的点,那么把x向保护它的点连边.那么题目就转化成了最大权闭合子图的问题. 但是这个图有点特殊啊... 考虑有环的情况,显然这个环以 ...

  6. BZOJ 1565 植物大战僵尸(最大权闭合图)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1565 题意:植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: ...

  7. codeforces 1082G - Petya and Graph 最大权闭合子图 网络流

    题意: 让你选一些边,选边的前提是端点都被选了,求所有的边集中,边权和-点权和最大的一个. 题解: 对于每个边建一个点,然后就是裸的最大权闭合子图, 结果比赛的时候我的板子太丑,一直T,(不会当前弧优 ...

  8. hiho# 1398 最大权闭合子图 网络流

    题目传送门 题意:给出n个活动,m个人,请人需要花费$a[i]$的钱,举办一次活动可以赚$b[i]$的钱,但是需要固定的几个人在场,一个人只需要请一次后就必定在场,问最大收益. 思路: 下列结论来自h ...

  9. Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序

    题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:p ...

随机推荐

  1. JS 对java返回的json格式的数据处理

    var dataObj=eval("("+res+")"); alert(dataObj.billBuy) //res是如下的数据 {"billBuy ...

  2. get与post提交方式区别?

    1.get <!--表单数据作为HTTP GET请求发送给action 规定的URL,并将数据附加在URL之后,由客户端直接发送给服务器.表单数据不能太长,也不能含有非ASCII码的字符--&g ...

  3. jQuery入坑指南

    前言 Ajax官方文档 爱jQuery jQuery插件库 jQuery中文api input 赋值和取值 记录一下: 在写一个input赋值,二话不说就直接利用了$('#xx').val()来进行取 ...

  4. mybatis基础学习5---懒加载和缓存

    1:懒加载 1)在主配置文件设置(要放在配置文件最前面) 1 <!-- 延迟加载配置,两个都必须同时有 --> <settings> 3 <!-- lazyLoading ...

  5. Linux 常用命令十二 top

    一.top命令 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. top显示系统当前的进程和其他状况,是一个动态显示过程,即可以 ...

  6. NOIp 2010/Luogu P1525 关押罪犯 【二分图/并查集】 By cellur925

    题目传送门 感想:相信自己的想法!继续挖掘! 读完题目后:看到的最大值最小?二分答案啊!再仔细一看:wi达到了1e9,二分可能费点劲.(其实真的是可以的)而且check函数貌似并没有什么行之有效的写法 ...

  7. 【洛谷3822】[NOI2017] 整数(线段树压位)

    题目: 洛谷 3822 分析: 直接按题意模拟,完了. 将每次加 / 减拆成不超过 \(32\) 个对单独一位的加 / 减. 考虑给一个二进制位(下称「当前位」)加 \(1\) 时,如果这一位本来就是 ...

  8. bryce1010专题训练——线段树习题汇总

    一.区间查询,无单点更新 hdu2795 Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  9. 逆序数 UVALive 6508 Permutation Graphs

    题目传送门 /* 题意:给了两行的数字,相同的数字连线,问中间交点的个数 逆序数:第一行保存每个数字的位置,第二行保存该数字在第一行的位置,接下来就是对它求逆序数 用归并排序或线段树求.想到了就简单了 ...

  10. 2016/10/29 Action类中execute方法的使用

    第一步:先配置web.xml文件 <filter> <filter-name>struts2</filter-name> <filter-class>o ...