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个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...
随机推荐
- eclipse+tomcat配置远程debug调整
由于开发环境与真实服务器环境存在差异,有时开发时明明正常的逻辑,部署之后就会出现各种各样的问题,通过日志邮不能明确定位到问题的时候,可以采用远程debug调试来定位问题.下面就介绍一下具体的配置步骤: ...
- spark 执行架构
术语定义 Application:Spark Application的概念和Hadoop MapReduce中的类似,指的是用户编写的Spark应用程序,包含了一个Driver 功能的代码和分布在集群 ...
- redis 问题记录
摘抄来自:https://zhuoroger.github.io/ 1.slowlog和排队延时 slowlog是排查性能问题关键监控指标.它是记录Redis queries运行时间超时特定阀值的系统 ...
- excell 导入 导出
1.jar包 2.POIUtils工具类 package com.esstglobal.service.utils; import java.io.BufferedInputStream; impor ...
- PostFix支持SMTP认证
安装cyrus-sasl yum -y install cyrus-sasl* 启动服务,开机启动 service saslauthd start chkconfig saslauthd on 配置p ...
- 「日常训练&知识学习」单调栈
这几天的知识学习比较多,因为时间不够了.加油吧,为了梦想. 这里写几条简单的单调栈作为题解记录,因为单调栈的用法很简单,可是想到并转化成用这个需要一些题目的积淀. 相关博客参见:https://blo ...
- Selenium(Python) ddt读取Excel文件数据驱动
首先, 引入xlrd模块: ExcelDDT.py: import unittestfrom time import sleep from ddt import ddt, datafrom selen ...
- python 终极篇 --- django 视图系统
Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误, ...
- 《Git学习指南》学习笔记(三)
多次提交 提交一般分未两步:add和commit. add将修改存入到索引(index)或叫暂存区(staging area)中. status命令 status命令会出现三种可能的状态: chang ...
- Jamie and Alarm Snooze
Description Jamie loves sleeping. One day, he decides that he needs to wake up at exactly hh: mm. Ho ...