P2805 [NOI2009]植物大战僵尸(最小割+拓扑排序)
题意:
n*m的矩阵,每个位置都有一个植物。每个植物都有一个价值(可以为负),以及一些它可以攻击的位置。从每行的最右面开始放置僵尸,僵尸从右往左行动,当僵尸在植物攻击范围内时会立刻死亡。僵尸每到一个位置可以获得该位置植物的价值。僵尸可以无限放置,求最大的价值和。
题解:
这种模型好像叫做最大权闭合子图。
首先通过拓扑排序将成环的点(即植物互相保护无法走到的点)删掉。
之后对于剩下的点A,若w > 0,则S→A连权值为w的边。
若w < 0,则A→T连权值为-w的边。
若A保护B(即B在A攻击范围内),则B→A连权值为INF的边。
注意每个点也被它右面的点保护。
最后跑一边最小割,答案为:正的价值和(即w > 0的和) - 最小割。
#include <bits/stdc++.h>
using namespace std;
const int N = ;
const int INF = 2e9;
int n, m;
int level[N];
int iter[N];
int x, y;
int w[N], d[N];
vector<int> g[N];
vector<int> a;
struct edge {
int to, cap, rev;
};
vector<edge> G[N];
void add_edge(int from, int to, int cap) {
G[from].push_back((edge){to, cap, G[to].size()});
G[to].push_back((edge){from, , G[from].size()-});
}
void bfs(int s) {
memset(level, -, sizeof(level));
queue<int> que;
level[s] = ;
que.push(s);
while(!que.empty()) {
int v = que.front(); que.pop();
int len = G[v].size();
for(int i = ; i < len; i++) {
edge &e = G[v][i];
if(e.cap > && level[e.to] < ) {
level[e.to] = level[v]+;
que.push(e.to);
}
}
}
}
int dfs(int v, int t, int f) {
if(v == t) return f;
int len = G[v].size();
for(int &i = iter[v]; i < len; i++) {
edge &e = G[v][i];
if(e.cap > && level[v] < level[e.to]) {
int d = dfs(e.to, t, min(f, e.cap));
if(d > ) {
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return ;
}
int max_flow(int s, int t) {
int flow = ;
for(;;) {
bfs(s);
if(level[t] < ) return flow;
memset(iter, , sizeof(iter));
int f;
while((f = dfs(s, t, INF)) > ) flow += f;
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = ; i <= n*m; i++) {
int num;
scanf("%d%d", &w[i], &num);
while(num--) {
scanf("%d%d", &x, &y);
int id = x*m+y+;
g[i].push_back(id);
d[id]++;
}
if(i % m != ) g[i].push_back(i-), d[i-]++;
}
queue<int> q;
for(int i = ; i <= n*m; i++) if(!d[i]) q.push(i);
while(!q.empty()) {
int v = q.front(); q.pop();
a.push_back(v);
int len = g[v].size();
for(int i = ; i < len; i++) {
int to = g[v][i];
d[to]--;
if(!d[to]) q.push(to);
}
}
int sum = ;
int len = a.size();
for(int i = ; i < len; i++) {
int v = a[i];
if(w[v] >= ) {
sum += w[v];
add_edge(, v, w[v]);
}
else add_edge(v, n*m+, -w[v]);
int up = g[v].size();
for(int j = ; j < up; j++) add_edge(g[v][j], v, INF);
}
printf("%d\n", sum-max_flow(, n*m+));
}
P2805 [NOI2009]植物大战僵尸(最小割+拓扑排序)的更多相关文章
- BZOJ 1565: [NOI2009]植物大战僵尸( 最小割 )
先拓扑排序搞出合法的, 然后就是最大权闭合图模型了.... --------------------------------------------------------------------- ...
- 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告
P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...
- P2805 [NOI2009]植物大战僵尸 (拓扑排序 + 最小割)
题意:N*M的矩阵 每个点上都有一颗植物 僵尸只能从每一行的最右边向左进攻 每个植物有攻击范围 可以保护在攻击范围内的植物 同时每一颗植物也保护他左边的植物 摧毁每个植物能获得价值 如果这个植物被保护 ...
- P2805 [NOI2009]植物大战僵尸 + 最大权闭合子图 X 拓扑排序
传送门:https://www.luogu.org/problemnew/show/P2805 题意 有一个n * m的地图,你可以操纵僵尸从地图的右边向左边走,走的一些地方是有能量值的,有些地方会被 ...
- BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)
题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...
- 洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流
正解:网络流 解题报告: 传送门$QwQ$ 题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价( ...
- BZOJ 1565 Luogu P2805 [NOI2009]植物大战僵尸 (Tarjan判环、最小割)
我: "立个flag 14点之前调完这题" 洛谷AC时间: 2019-06-24 14:00:16 实力打脸... 网络流板子从来写不对系列 题目链接: (BZOJ) https: ...
- Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序
题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:p ...
- b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图
b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...
随机推荐
- C#原型模式
如下: [Serializable] public class ModelNewTable : ICloneable { public object Clone() { using (var stre ...
- php随机类型验证码
开发使用验证码的意义就是为了区别操作者是人还是机器,防止自动脚本对服务器造成灾难性的攻击 目前有各种各样的验证码种类,譬如:静态字符验证码.算术验证码.拖拽验证码.识别文字或识别物品验证码(高级),下 ...
- Eclipse 常用快捷键 个性设置(Mac)
推荐编程使用Mac 要是非要一个原因 那就是Apple工程师用Mac Google工程师也用Mac 1. 常用快捷键 Mac自带 Command + ← 跳到当前文本行头 Command + → ...
- SQL语言重点学习
数据库的操作任务通常包括以下几个方面: 1.查询数据. 2.在表中插入,修改和删除记录. 3.建立,修改和删除数据对象. 4.控制对数据和数据对象的读写. 5.保证数据库一致性和完整性. SQL语言学 ...
- [SHELL]shell中变量的使用
1.输出变量 : #! /bin/bash my_var=BOB echo $my_var echo "hi,$my_var" echo "the price is \$ ...
- dotnetframe的清理工具
微软的产品一向不敢恭维,卸载都没有办法卸载干净,卸载又慢又不彻底,dotnet被我卸载之后还有注册表残留以至于无法重新安装. .NET Framework Cleanup Tool真的很好用,全部版本 ...
- 基础数据类型-tuple
Python中,元组tuple与list类似,不同之处在于tuple的元素不能修改,tuple使用(),list使用[], (1)元组的创建使用(),需要注意的是创建包含一个元素的元组: tuple_ ...
- Python中的相对导入语法
Python中支持相对导入语法,即可以相对于某一个package进行导入,具体语法如下: # 导入"./dir2/spam.py", .表示当前目录 from .dir2 impo ...
- 20162328蔡文琛week03
学号 2006-2007-2 <程序设计与数据结构>第X周学习总结 教材学习内容总结 在第三章,我学习到了更多有关于java.util包的知识.了解了多个引用变量可以指向同一个对象.而且J ...
- 软件工程课堂作业(三)——Right-BICEP软件单元测试
一.测试方法:Right-BICEP Right-结果是否正确?B-是否所有的边界条件都是正确的?I-能查一下反向关联吗?C-能用其他手段交叉检查一下结果吗?E-你是否可以强制错误条件发生?P-是否满 ...