题意:

  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]植物大战僵尸(最小割+拓扑排序)的更多相关文章

  1. BZOJ 1565: [NOI2009]植物大战僵尸( 最小割 )

    先拓扑排序搞出合法的, 然后就是最大权闭合图模型了.... --------------------------------------------------------------------- ...

  2. 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告

    P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...

  3. P2805 [NOI2009]植物大战僵尸 (拓扑排序 + 最小割)

    题意:N*M的矩阵 每个点上都有一颗植物 僵尸只能从每一行的最右边向左进攻 每个植物有攻击范围 可以保护在攻击范围内的植物 同时每一颗植物也保护他左边的植物 摧毁每个植物能获得价值 如果这个植物被保护 ...

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

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

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

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

  6. 洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价( ...

  7. BZOJ 1565 Luogu P2805 [NOI2009]植物大战僵尸 (Tarjan判环、最小割)

    我: "立个flag 14点之前调完这题" 洛谷AC时间: 2019-06-24 14:00:16 实力打脸... 网络流板子从来写不对系列 题目链接: (BZOJ) https: ...

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

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

  9. b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图

    b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...

随机推荐

  1. Mac brew安装redis

    1.安装redis $ brew install redis Error:Failed to download resource "reds"  // 下载reds失败 不过不需要 ...

  2. Vue框架核心之数据劫持

    本文来自网易云社区. 前瞻 当前前端界空前繁荣,各种框架横空出世,包括各类mvvm框架横行霸道,比如Angular.Regular.Vue.React等等,它们最大的优点就是可以实现数据绑定,再也不需 ...

  3. Oracle DELETE和TRUNCATE 的区别

    语法delete from aa truncate table aa 区别 1.delete from后面可以写条件,truncate不可以. 2.delete from记录是一条条删的,所删除的每行 ...

  4. 抓取Oracle数据快照

    进入到oracle安装目录下的admin(找到这个目录)开启cmd键入sqlplus system/mima@实例名>@awrrpt.sql Would you like an HTML rep ...

  5. 使用InstallShield-Limited-Edition制作安装包

    1.打开此网站,进行注册,获取序列码以及下载InstallShield-Limited-Edition 2.安装完成之后,打开VisualStudio,新建项目 3.填写基本应用信息 4.配置相关信息 ...

  6. eclipse格式化

    一.eclipse格式化的必要性 1.便于阅读 2.便于协作 二.eclipse格式化快捷键 ctrl shift + F

  7. python内建模块Collections

    # -*- coding:utf-8 -*- # OrderedDict可以实现一个FIFO(先进先出)的dict, # 当容量超出限制时,先删除最早添加的Key: from collections ...

  8. django启动创建用户失败

    a django应用启动 b 访问127.0.0.1:8000,报错信息如下,原因为没有这个用户需要创建下用户 c 创建用户过程中报错原因是因为添加了app需要告诉django,这个 模型发生了改变, ...

  9. Python—列表(一个“打了激素”的数组)

    我们在C语言中会使用数组来将一大堆数据类型一样的数据挨个摆在一起,但是数组有一个基本的要求,就是数据类型必须是一致的,我们知道Python的变量由于没有数据类型,也就是说Python没有数组这一概念, ...

  10. springboot 整合apache shiro

    这几天因为项目需要,学习了下shiro,由此留下一些记录,也希望对初学shiro的朋友有帮助. springboot 是这两年新兴起来的一个项目,它的出现是为了减少springmvc开发过程中需要引入 ...