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进攻. ...
随机推荐
- Spring远程调用技术<1>-RMI
在java中,我们有多种可以使用的远程调用技术 1.远程方法调用(remote method invocation, RMI) 适用场景:不考虑网络限制时(例如防火墙),访问/发布基于java的服务 ...
- sicily 猴子选大王
题目描述 猴子选大王,有N只猴子,从1-N进行编号.它们按照编号的顺时针方向,排成一个圆圈,然后从第一只猴子开始报数.第一只猴子报1,以后每只猴子报的数字都是它前面猴子所报数字加1.如果一只猴子报的数 ...
- ArrayList 保证多线程安全
一:使用synchronized关键字 二:使用Collections.synchronizedList();使用方法如下: 假如你创建的代码如下:List<Map<String,Obje ...
- Winform无边框窗体的移动和阴影
//窗体移动API [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport ...
- K - 迷宫问题
/*定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, ...
- django model Meta选项
可用的 Meta 选项 abstract Options.abstract 如果 abstract = True ,这个 model 就是一个 抽象基类 . app_label Options.app ...
- 【OpenJudge 1793】矩形覆盖
http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...
- Centos7下安装python,查看python版本
安装Centos的时候,一般会自带默认安装python2.x 一般用python -V可以查看python版本. 我当时安装的时候,运行了那个语句,但是却显示了一大堆出来,虽然里面也带有版本信息,但是 ...
- 让你Android开发更简单
转载:http://www.jianshu.com/p/22ff8b5fdadc 搭建一个新的Android项目,你会怎么做? 每个人对应用框架的理解不相同,但是最终达到的效果应该是一样: ①降低项目 ...
- Servlet实现asp.net中的Global.asax启动事件(Servlet和Listener使用)
1.Java Web中没有像asp.net的全局启动事件,但是可以通过web.xml中的load-on-startup节点来控制Servlet的开机启动和启动次数.web.xml详细配置参考:http ...