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个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...
随机推荐
- Habse中Rowkey的设计原则——通俗易懂篇
Hbase的Rowkey设计原则 一. Hbase介绍 HBase -> Hadoop Database,HBase是Apache的Hadoop项目的子项目.HBase不同于一般的关系数据库,它 ...
- Drupal中自定义登录页面
通过覆写template定义新的user_login表单来为自定义登录页面.方法: 1. 本站使用的主题是Rorty.来到\sites\all\themes\rorty,打开template.php ...
- ORA-15032、ORA-15071错误处理
遇到一下错误 ERROR at line 1: ORA-15032: not all alterations performed ORA-15071: ASM disk "NOCR_0002 ...
- iOS 开发库相关(持续更新)
01-给任意view添加毛玻璃效果 https://github.com/JagCesar/iOS-blur 02-浮动式的textfield输入框(可用于登录界面) https://github ...
- generator-ivweb 基于react-redux的多页脚手架
背景 每个公司甚至每个项目组,在开发新项目的时候都会有一些自己特色的东西,比如公共组件,ajax请求拦截处理,内部积累的一些业务逻辑等等,如果没有自己的脚手架,那么拷贝代码成为常态,每个项目的结构,甚 ...
- Selenium 入门到精通系列:三
Selenium 入门到精通系列 PS:Driver_Element 常用方法 例子 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2 ...
- lintcode 二叉树中序遍历
/** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * Tr ...
- 解决jQuery不同版同时引用的冲突
今天研发的同事在开发一个新jQuery插件时,遇到一个揪心的问题.平台以前使用的 jQuery版本是1.2.6,偶,天啊!这是古代的版本啊! 由于很多功能基于老版本,不能删除啊,同志们都懂的! 于是我 ...
- [模板]非递归线段树(zkw的变异版本)
类似于zkw,但空间只用两倍,zkw要4倍. 链接 可以下传标记,打熟后很好码. #include <set> #include <cmath> #include <cs ...
- lsscsi命令详解
基础命令学习目录首页 lsscsi包默认是不安装的.lsscsi包安装完之后,lsscsi命令就可以使用了.lsscsi命令(lsscsi -t -L)能很方便的看出哪些是固态硬盘(SSD),哪些是S ...