BZOJ1565——[NOI2009]植物大战僵尸
1、题意:有一些点,点与点之间有保护关系,每个点都有一个权值,求能获得的最大值
2、分析:裸的最大权闭合图,用网络流进行求解,然后我们发现点与点之间的保护关系可能构成环,这样网络流是无法处理的,然后我们拓扑排序去掉那些不能获得的点。注意!!!!这里的环是不能用强连通来强行去掉的,因为——比如有一个点,他两端与它相连的点在环内,那么这个点你也去不掉
最大权闭合图模型:建立源点s和汇点t,将所有正权点连向s,容量为点权,将所有负权点连向t,容量为点权的相反数,原图中的边容量全部设成inf,跑一边最小割,用所有正权点的总和减一下就是答案了
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 500010
#define inf 214748364
inline int read(){
char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while('0' <= ch && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
namespace dinic{
struct Edge{
int from, to, cap, flow, next;
} G[M];
int head[M], cur[M], tot;
int vis[M], d[M];
int s, t;
inline void init(){
tot = -1;
memset(head, -1, sizeof(head));
}
inline void add(int u, int v, int w){
G[++ tot] = (Edge){u, v, w, 0, head[u]};
head[u] = tot;
G[++ tot] = (Edge){v, u, 0, 0, head[v]};
head[v] = tot;
}
inline bool BFS(){
memset(vis, 0, sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = 1;
d[s] = 0;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = head[x]; i != -1; i = G[i].next){
Edge& e = G[i];
if(e.cap > e.flow && !vis[e.to]){
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
inline int DFS(int x, int a){
if(x == t || a == 0) return a;
int flow = 0, f;
for(int &i = cur[x]; i != -1; i = G[i].next){
Edge& e = G[i];
if(d[e.to] == d[x] + 1 && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){
e.flow += f;
G[i ^ 1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
inline int ans(){
int flow = 0;
while(BFS()){
for(int i = s; i <= t; i ++) cur[i] = head[i];
flow += DFS(s, inf);
}
return flow;
}
}
int val[M];
struct Edge{
int u, v, next;
} G[M];
int head[M], tot;
int du[M], ok[M];
int n, m;
inline void addedge(int u, int v){
// printf("%d %d\n", u, v);
G[++ tot] = (Edge){u, v, head[u]};
head[u] = tot;
du[v] ++;
}
inline void toposort(){
queue<int> Q;
for(int i = 1; i <= n * m; i ++) if(!du[i]){
Q.push(i);
ok[i] = 1;
}
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = head[x]; i != -1; i = G[i].next){
du[G[i].v] --;
if(!du[G[i].v]){
Q.push(G[i].v);
ok[G[i].v] = 1;
}
/*puts("fuck");
printf("%d\n", i);*/
}
}
}
int main(){
n = read(), m = read();
#define Num(i, j) (i - 1) * m + j
memset(head, -1, sizeof(head));
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
int num = Num(i, j);
val[num] = read(); int op = read();
for(int k = 1; k <= op; k ++){
int x = read(), y = read();
x ++; y ++;
addedge(num, Num(x, y));
}
if(j != m) addedge(num + 1, num);
}
}
toposort();
//puts("fuck");
dinic::s = 0; dinic::t = n * m + 1;
dinic::init();
int res = 0;
for(int i = 1; i <= n * m; i ++) if(ok[i]){
if(val[i] > 0) res += val[i], dinic::add(dinic::s, i, val[i]);
else dinic::add(i, dinic::t, -val[i]);
for(int j = head[i]; j != -1; j = G[j].next){
if(ok[G[j].v]){
dinic::add(G[j].v, i, inf);
}
}
}
printf("%d\n", res - dinic::ans());
return 0;
}
BZOJ1565——[NOI2009]植物大战僵尸的更多相关文章
- 【最大权闭合子图 tarjan】bzoj1565: [NOI2009]植物大战僵尸
dinic+tarjan板子练手题 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其 中P ...
- BZOJ1565: [NOI2009]植物大战僵尸
Description Input Output 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. Sample Input 3 2 10 0 20 0 ...
- 【bzoj1565】 NOI2009—植物大战僵尸
http://www.lydsy.com/JudgeOnline/problem.php?id=1565 (题目链接) 题意 给出$n*m$的棋盘,僵尸攻击每个格子可以获得$v$的分数,每个格子又会保 ...
- 【bzoj1565】[NOI2009]植物大战僵尸
1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2164 Solved: 1001[Submit][Stat ...
- 图论(网络流):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 ...
- BZOJ 1565: [NOI2009]植物大战僵尸
1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2317 Solved: 1071[Submit][Stat ...
- 【刷题】BZOJ 1565 [NOI2009]植物大战僵尸
Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻. ...
随机推荐
- SpringMVC注入Spring的bean
一.Spring和SpringMVC两个IOC容器有什么关系呢? Spring的IOC容器包含了SpringMVC的IOC,即SpringMVC配置的bean可以调用Spring配置好的bean,反之 ...
- Struts2 OGNL案例
一>>原始类型与包装类型 先定义两个实体类User和Address User package cn.entity; public class User { private String n ...
- 玩转Unity资源,对象和序列化(上)
这是一系列文章中的第二章,覆盖了Unity5的Assets,Resources和资源管理 本文将从Unity编辑器和运行时两个角度出发,主要探讨以下两方面内容:Unity序列化系统内部细节以及Unit ...
- kettle启动“Error: could not create the Java Virtual Machine”
因为我的操作系统是32bit,而Ketttle的Spoon脚本中,默认是PENTAHO_DI_JAVA_OPTIONS="-Xms1024m" "-Xmx2048m&qu ...
- PAT 1035. 插入与归并(25)
根据维基百科的定义: 插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列.每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置.如此迭代直到全部元素有序. 归并排序进行如下迭 ...
- JSP中ResultSet的方法
1,如何获得ResultSet的结构 ResultSetMetaData rsmd=rs.getMetaData();cn=rsmd.getColumnCount();for(int ik=1;ik& ...
- ajax给全局变量赋值问题解决示例
今天在做项目时,遇到了一个问题.我用的是ajax,要在 ajax里面给一个全局变量赋值,结果死活赋值不上,纠结了好半天,后来上网查了查,才 知道,ajax默认是异步请求,(当要赋值时,此时的值没有拿到 ...
- BeautifulSoup 的用法
转自:http://cuiqingcai.com/1319.html Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python ...
- java-json日期字符串转换
String valueStr = value.toString(); if(StringUtils.isBlank(valueStr) || "null".equals(valu ...
- Java面试题总结(二)
43.Java中的两种异常类型是什么?他们有什么区别? Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常.不受检查的异常不需要在方法或者是构造函数上声明,就算 ...