「NOI2009」植物大战僵尸
「NOI2009」植物大战僵尸
传送门
这是一道经典的最大权闭合子图问题,可以用最小割解决(不会的可以先自学一下)
具体来说,对于这道题,我们对于两个位置的植物 \(i\) 和 \(j\) ,如果 \(j\) 可以保护 \(i\) ,也就是 \(i\) 在 \(j\) 的攻击范围内(特别的,我们认为一个植物也会被它右边的第一个植物保护),我们就连边 \(i \to j\),因为攻击一个植物的前提就是攻击掉所有保护它的植物,我们这样连边恰好可以满足闭合子图的性质。
但是我们还会碰到一个问题,那就是互相保护的情况,在图上也就是环的情况,我们发现一个环是不可能被攻击的,所以说我们只把没有位于环上的点用来建图,具体可以用反图+拓扑排序实现。
这样就解决了。
参考代码:
#include <cstring>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
template < class T > inline T min(T a, T b) { return a < b ? a : b; }
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 605, __ = 400005, INF = 2147483647;
int tot = 1, head[_]; struct Edge { int ver, cap, nxt; } edge[__ << 1];
inline void Add_edge(int u, int v, int d) { edge[++tot] = (Edge) { v, d, head[u] }, head[u] = tot; }
inline void link(int u, int v, int d) { Add_edge(u, v, d), Add_edge(v, u, 0); }
int n, m, a[_], able[_], dgr[_];
int s, t, dep[_], cur[_];
int num; struct node { int u, v; } p[__];
int hd, tl, Q[_];
inline int id(int i, int j) { return (i - 1) * m + j; }
inline int bfs() {
memset(dep, 0, sizeof (int) * (t - s + 1));
hd = tl = 0;
Q[++tl] = s, dep[s] = 1;
while (hd < tl) {
int u = Q[++hd];
for (rg int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].ver;
if (dep[v] == 0 && edge[i].cap > 0)
dep[v] = dep[u] + 1, Q[++tl] = v;
}
}
return dep[t] > 0;
}
inline int dfs(int u, int flow) {
if (u == t) return flow;
for (rg int &i = cur[u]; i; i = edge[i].nxt) {
int v = edge[i].ver;
if (dep[v] == dep[u] + 1 && edge[i].cap > 0) {
int res = dfs(v, min(flow, edge[i].cap));
if (res) { edge[i].cap -= res, edge[i ^ 1].cap += res; return res; }
}
}
return 0;
}
inline int Dinic() {
int res = 0;
while (bfs()) {
for (rg int i = s; i <= t; ++i) cur[i] = head[i];
while (int d = dfs(s, INF)) res += d;
}
return res;
}
inline void toposort() {
tot = 0, memset(head, 0, sizeof head);
for (rg int i = 1; i <= num; ++i) Add_edge(p[i].u, p[i].v, 0), ++dgr[p[i].v];
hd = tl = 0;
for (rg int i = 1; i <= n * m; ++i) if (dgr[i] == 0) Q[++tl] = i;
while (hd < tl) {
int u = Q[++hd]; able[u] = 1;
for (rg int i = head[u]; i; i = edge[i].nxt) if (!--dgr[edge[i].ver]) Q[++tl] = edge[i].ver;
}
}
int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), read(m), s = 0, t = n * m + 1;
for (rg int w, x, y, i = 1; i <= n; ++i)
for (rg int j = 1; j <= m; ++j) {
read(a[id(i, j)]), read(w);
while (w--) read(x), read(y), ++x, ++y, p[++num] = (node) { id(i, j), id(x, y) };
}
for (rg int i = 1; i <= n; ++i)
for (rg int j = 1; j < m; ++j) p[++num] = (node) { id(i, j + 1), id(i, j) };
toposort();
tot = 1, memset(head, 0, sizeof head);
for (rg int i = 1; i <= num; ++i) {
int u = p[i].u, v = p[i].v;
if (!able[u] || !able[v]) continue ;
link(v, u, INF);
}
int sum = 0;
for (rg int i = 1; i <= n * m; ++i) {
if (!able[i]) continue ;
if (a[i] > 0) link(s, i, a[i]), sum += a[i];
if (a[i] < 0) link(i, t, -a[i]);
}
printf("%d\n", sum - Dinic());
return 0;
}
「NOI2009」植物大战僵尸的更多相关文章
- 【BZOJ1565】【NOI2009】植物大战僵尸
好久没写博客了 题目 题目在这里 思路&做法 没什么好说的 应该很容易看出是 最大闭合子图 吧? 不过要注意一下的是,这题 可能有植物是不可能被击溃的 , 所以要先跑一遍 拓扑排序 把这些点排 ...
- [Android] 转移“植物大战僵尸2”存档的办法,无需root
作者:zyl910 查过了很多文章,都说需要root后才能转移存档.但很多时候是不能root的,此时该怎么办呢? 我研究了很久,最终找到了一种办法,无需root也能转移存档. 一.备份 我用的是联想手 ...
- 32位汇编第六讲,OllyDbg逆向植物大战僵尸,快速定位阳光基址
32位汇编第六讲,OllyDbg逆向植物大战僵尸,快速定位阳光基址 一丶基址,随机基址的理解 首先,全局变量的地址,我们都知道是固定的,是在PE文件中有保存的 但是高版本有了随机基址,那么要怎么解决这 ...
- 原生JS实现的h5小游戏-植物大战僵尸
代码地址如下:http://www.demodashi.com/demo/12755.html 项目介绍 本项目是利用原生js实现的h5小游戏-植物大战僵尸,主要结合了一下自己对于h5小游戏的理解,结 ...
- 植物大战僵尸:寻找阳光掉落Call调用
实验目标:通过遍历阳光产生的时间,寻找阳光产生的本地Call,使用代码注入器注入,自定义生成阳光 阳光CALL遍历技巧: 进入植物大战僵尸-> 当出现阳光后->马上搜索未知初始数值 返回游 ...
- java小项目之:植物大战僵尸,这个僵尸有点冷!内附素材源码
Java小项目之:植物大战僵尸! <植物大战僵尸>是由PopCap Games开发的一款益智策略类单机游戏,于2009年5月5日发售,这款游戏可谓是无人不知无人不晓. 在我身边,上到40岁 ...
- 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸
410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:pvz.out 简单对比时间限制:2 s 内存限制:512 MB [问题描述] Plants vs ...
- P2805 [NOI2009]植物大战僵尸
题目地址:P2805 [NOI2009]植物大战僵尸 最大权闭合子图 若有向图 \(G\) 的子图 \(V\) 满足: \(V\) 中顶点的所有出边均指向 \(V\) 内部的顶点,则称 \(V\) 是 ...
- COGS410. [NOI2009] 植物大战僵尸
410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:pvz.out 简单对比时间限制:2 s 内存限制:512 MB [问题描述] Plants vs ...
随机推荐
- ColorPix——到目前为止最好用的屏幕取色器
分享一个颜色取色器网页.PPT.EXCEL配色不再烦恼 简单易用 大家做商业.企业报告的时候是不是经常遇到要调色的困扰呢?PPT.EXCEL等颜色选取会对报告有质的影响!!要更专业要更有美感!给大家分 ...
- JDBC简单代码
1..写简单sql语句执行 DROP TABLE IF EXISTS `jdbctest`; CREATE TABLE `jdbctest` ( `id` ) NOT NULL AUTO_INCREM ...
- Bugku-CTF之文件包含2 (150)
Day37 文件包含2
- 短网址(t.cn、url.cn)生成,网址缩短接口API
简要说明 短网址api接口有很多格式,不同的接口生成的短网址格式也不同,比如常见的t.cn.url.cn.w.url.cn等格式.总而言之短网址接口就是用来将一个冗长的链接缩短成10个字符以内的短链接 ...
- Java出现NoSuchElementException异常
参考网址:https://blog.csdn.net/xiao_ma_csdn/article/details/78906650 出现这个异常是线程访问越界,这个时候就要检查下到底是哪里越界. 原因是 ...
- 前端——语言——Core JS——《The good part》读书笔记——第三章节(Object)
本章介绍对象. 在学习Java时,对象理解为公共事物的抽象,实例为具体的个例,对象为抽象的概念,例如人为抽象的概念,具体的个例为张三,李四. Java对象种类多,包含普通类,JavaBean,注解,枚 ...
- star_namelist
Yua Mikami Shion Utsunomiya Mizuho Uehara Yui Hatano 波多野结衣 Tsubasa Amami Rei Mizuna 水菜丽 Eimi Fukada ...
- XMOS发布集单片机,AI,FPGA,DSP于一身的跨界处理器完全体xcore.ai,致力于AIOT,售价1美元起步
说明:XMOS这次致力于打造全新的,颠覆性的嵌入式平台,简化开发人员要学一堆东西才能开发一款高性能AIOT产品的痛点. XCORE.AI集单片机,AI,FPGA,DSP于一身,嵌入式软件开发人员可以灵 ...
- NET com组件注册
1.签名 右击项目->属性->[签名]标签, 选中[为程序集签名]–>[选择强名称密钥文件]–>[新建],输入你的密钥名称,去掉[使用密码保护密钥文件] 最重要的签名,并且注册 ...
- css与js基础
CSS样式 1 宽高设置 块元素可使用 wid 1字体 font-family : 文本类型 font-size 字体大小 font-style 字体样式 斜体italic 正常norm ...