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

Solution

  按照依赖关系建立有向图:若清除$a$前必须清除$b$,则连边$a$至$b$。这些依赖关系包括同行植物左边对右边的依赖,以及被保护者对保护者的依赖。

  首先不能考虑开挂集团,也就是依赖关系成强联通分量的植物,也包括能通过依赖关系走到强联通分量的植物——它们都无敌,需要排除掉。这可以用tarjan加上反向边的深搜预处理。

  

  一个植物能够下手,当且仅当其出度为0.

  每一株植物又是带正负权值的,那么明显是要在依赖图中,求一个最大权闭合子图。也就是要有植物起手(迎合闭合的性质,出边都在闭合子图内,即依赖的植物都要一起干掉,都应该在闭合子图的范围内),且干掉的植物权值和最大。

  按照最大权闭合子图的建立方法:源点向所有正权点连容量为其权值的边,所有负权点向汇点连容量为其权值绝对值的边;所有节点按依赖关系连边,容量为$+\infty$。

  答案是所有正权点点权值和减去最大流。能将负权转化为正权来跑网络流的原因,拆拆括号就可以发现,这是很巧妙的。


#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
const int N=610,INF=2147000000;
int n,m,a[N],h[N],hr[N],tot;
int dfn[N],low[N],tmcnt,is[N],st[N],top,ins[N],vis[N];
int S,T,dis[N],cur[N];
int sum;
queue<int> q;
vector<int> list[N];
struct Edge{int v,f,next;}g[1000010];
inline int min(int x,int y){return x<y?x:y;}
inline int id(int x,int y){return (x-1)*m+y;}
inline void addEdge(int u,int v){g[++tot].v=v; g[tot].next=h[u]; h[u]=tot;g[++tot].v=u; g[tot].next=hr[v]; hr[v]=tot;
}
inline void addEdge(int u,int v,int f){g[++tot].v=v; g[tot].f=f; g[tot].next=h[u]; h[u]=tot;g[++tot].v=u; g[tot].f=0; g[tot].next=h[v]; h[v]=tot;
}
bool bfs(){while(!q.empty()) q.pop();q.push(S);for(int i=1;i<=T;i++) dis[i]=-1;dis[S]=0;while(!q.empty()){int u=q.front(); q.pop();for(int i=h[u],v;i;i=g[i].next)if(g[i].f&&dis[v=g[i].v]==-1){dis[v]=dis[u]+1;if(v==T) return true;q.push(v);}}return dis[T]!=-1;
}
int dfs(int u,int delta){if(u==T) return delta;int ret=0,get;for(int i=cur[u],v;i&&delta;i=g[i].next)if(g[i].f&&dis[v=g[i].v]==dis[u]+1){get=dfs(v,min(delta,g[i].f));g[i].f-=get; g[i^1].f+=get;if(g[i].f) cur[u]=i;delta-=get; ret+=get;}if(!ret) dis[u]=-1;return ret;
}
int dinic(){int ret=0;while(bfs()){for(int i=1;i<=T;i++) cur[i]=h[i];ret+=dfs(S,INF);}return ret;
}
void tarjan(int u,int fa){dfn[u]=low[u]=++tmcnt;st[++top]=u; ins[u]=1;for(int i=h[u],v;i;i=g[i].next){v=g[i].v;if(!dfn[v]){tarjan(v,u);low[u]=min(low[u],low[v]);}else if(ins[v])low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){if(st[top]==u){ins[u]=0;top--;return;}int x;do{x=st[top--];ins[x]=0;is[x]=1;}while(x!=u);}
}
void clear(int u){vis[u]=1; is[u]=1;for(int i=hr[u],v;i;i=g[i].next)if(!vis[v=g[i].v])clear(v);
}
int main(){freopen("input.in","r",stdin);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int k=id(i,j),l,x,y;scanf("%d%d",&a[k],&l);while(l--){scanf("%d%d",&x,&y);addEdge(id(x+1,y+1),k);list[id(x+1,y+1)].push_back(k);}}for(int i=1;i<=n;i++)for(int j=1;j<m;j++)addEdge(id(i,j),id(i,j+1));for(int i=1,up=n*m;i<=up;i++) if(!dfn[i]) tarjan(i,0);for(int i=1,up=n*m;i<=up;i++)if(!vis[i]&&is[i])clear(i);for(int i=1,up=n*m;i<=up;i++) h[i]=0;tot=1;S=n*m+1; T=n*m+2;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){int x=id(i,j);if(j<m&&!is[x]&&!is[id(i,j+1)])addEdge(x,id(i,j+1),INF);if(is[x]) continue;if(a[x]>=0){addEdge(S,x,a[x]);sum+=a[x];}else addEdge(x,T,-a[x]);int sz=list[x].size();for(int k=0;k<sz;k++)addEdge(x,list[x][k],INF);}int maxflow=dinic();    printf("%d\n",sum-maxflow);return 0;
}

奇妙代码

  

转载于:https://www.cnblogs.com/RogerDTZ/p/8016697.html

【BZOJ1565】 植物大战僵尸相关推荐

  1. bzoj-1565 植物大战僵尸

    题意: 给出一片n*m的草坪,上面每个点有一个植物: 现在由你来从最右面放出一些僵尸来进攻这些植物: 僵尸到一个植物面前的时候就可以吃掉这个植物,并且得到这个植物的的得分(可正可负): 每个植物可以攻 ...

  2. [BZOJ1565]植物大战僵尸

    如果$x$可以攻击$y$,那么选了$y$就一定要选$x$,并且选了$x$就一定要选$x$右边的格子,格子还有权值,这就是最大权闭合子图的模型了,但是注意到图中可能存在环,直接拓扑排序忽略环即可 在这篇 ...

  3. 女友让我破解植物大战僵尸!我干脆撸了一款一样的....翻身舔狗把歌唱呀

    今天给大家分享的开源项目可以说非常适合入门,还比较好玩,更是一个有故事的项目.既能满足想学习的读者,又能满足那些喜欢八卦的读者. 提到植物大战僵尸相信大部分读者都不陌生,可以说是塔防类游戏的鼻祖.就鸟 ...

  4. 【植物大战僵尸2】算法 笔记

    文章目录 春日活动--旅行原木--特殊事件--植物挑战_超能花菜 春日活动--暖春植树--初春挑战 地图解锁顺序建议 花园战争 超z联赛 无尽挑战 无尽常用植物及装扮 植物排名 春日活动–旅行原木–特 ...

  5. pvz安卓服务器维修礼包码,植物大战僵尸2礼包兑换码大全2020最新版

    植物大战僵尸2礼包码2020最新版是一款能够让玩家体验烧脑塔防大战的放置游戏,拥有经典的游戏规则设计,带来的玩法也会让每个玩家体验最为精彩的体验,每个僵尸都有着自己的特性,游戏之中的每一种植物都有自己 ...

  6. [日记]游长白遇梅花,植物大战僵尸

    "旅客朋友们--"我因为坐在面包车副驾驶的位置,所以假装自己是导游,"您即将经过的景点是'董眼镜修车铺',请向车窗的左侧观看--" 董眼镜修车铺 "董 ...

  7. 基于python开发植物大战僵尸

    目录 摘要 2 一, 引言 3 1.1中国游戏产业的现状 3 1.2中国游戏产业的未来发展局势 4 1.3植物大战僵尸游戏的发展状况 4 二.系统结构 5 2.1 Python3.8.2 IDLE 简 ...

  8. 植物2 IOS 怎么实名认证_植物大战僵尸2未来世界22天困难怎么过关 植物阵容推荐...

    植物大战僵尸2未来世界22天困难攻略 植物大战僵尸2未来世界22天有很多小伙伴都卡在这里,难度是一定的,那么到底要怎么过呢?下面就和小编一起去了解一下吧! 植物大战僵尸未来世界第二十二天过关条件是指挥 ...

  9. 谈 Scratch 版“植物大战僵尸”

    请先查看  Scratch经典游戏作品:植物大战僵尸  并下载资源. Python 版"植物大战僵尸"下载链接:https://download.csdn.net/download ...

  10. 计蒜客-植物大战僵尸

    嘟嘟最近迷恋上了一款游戏:植物大战僵尸.在梦中,他梦到了一个更加刺激的植物大战僵尸版本.有 n 个僵尸从起点出发,每个僵尸占用一个独立的直线道路.第 i 个僵尸在第一秒的速度为 f_if​i​​ ,之 ...

最新文章

  1. 汇总下几个IP计算/转换的shell小脚本-转
  2. matplotlib color可选
  3. SyntaxError:identifier starts immediately after numeric literal
  4. linux 一切都是文件_一切都是文件
  5. 三种代理服务器以及反向代理详解
  6. java 读取excel 文件 Unable to recognize OLE stream 错误
  7. JdbcTemplate简单介绍
  8. mysql 主主复制
  9. MySQL高可用之MHA的搭建 转
  10. Win7版IE10下载包中暗藏了DirectX 11.1
  11. js 刷新,返回上一步,前进,后退,
  12. 无线路由器实现网络接入
  13. 天龙八部排名(三联版)
  14. 计算机里的声卡的主要作用,声卡是什么?他的主要作用有哪些?
  15. monthcalendar控件
  16. choco安装[win10包管理器]
  17. php 验证手机号码格式
  18. 一分钟教会你音频配音乐怎么制作
  19. 已安装visual studio 如何添加新模板和组件
  20. Hibernate5自动建表坑之索引BUG(Cant DROP xxxxxxxxx check that column/key exists)

热门文章

  1. react 项目 测试
  2. 17 类的成员 私有
  3. 跨域通信——多窗口通信
  4. Spring中使用 InitializingBean
  5. MySQL查询当天、本周,本月,上一个月的数据
  6. 【转】英文版XP不能安装中文版软件
  7. 如何获取jar包的在执行机上面的路径
  8. 类型②typeof 操作符
  9. java robots协议检测工具
  10. 我也是不得不说我的学习能力下降了,这两天都没有完成一个模块