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进攻. ...
随机推荐
- 配置oracle instance client
1,下载oracle instance client.http://www.oracle.com/technetwork/database/features/instant-client/index- ...
- Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案
的最佳方案 标签: Android屏幕旋转AsyncTaskProgressDialog 2014-07-19 09:25 39227人阅读 评论(46) 收藏 举报 分类: [android 进阶之 ...
- 关于refs/for/ 和refs/heads/
1. 这个不是git的规则,而是gerrit的规则, 2. Branches, remote-tracking branches, and tags等等都是对commite的引用(re ...
- 【C#】【Thread】SpinLock
SpinLock结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型的锁. 不过,我们建议您仅在通 ...
- StackExchange.Redis通用封装类分享(转)
阅读目录 ConnectionMultiplexer 封装 RedisHelper 通用操作类封 String类型的封装 List类型的封装 Hash类型的封装 SortedSet 类型的封装 key ...
- linux-windows资源共享
先安装samba,然后 sudo mount -t cifs //192.168.1.111/Jack_Win_Share /media/ -o username=Jack,password=1,io ...
- 【翻译】DotNetMQ: 一个.NET版完整的消息队列系统
在一个大型的分布式系统中,消息队列是不可缺少的中间件,能很好的解决异步消息.应用解耦.均衡并发等问题.在.net中,偶然发现一个效率不错.安全可靠.功能齐全的消息组件,忍不住翻译过来,供大家快速预览. ...
- 【原创】O2O,你真的知道怎么玩吗?
自从2011年8月份,O2O的概念被Alex Rampell提出,并且在当年的11月份被引入中国以来,O2O这一概念就好像给久无新意的中国互联网行业,打了一针兴奋剂.O2O这个词也如麦当劳,星巴克这些 ...
- go 聊天室简单版总结
/* * 思路:在登录成功时将用户的id存进在线用户列表中的key value中链接的ws为空,并保存用户的信息. * 当跳转到聊天室时,将用户和聊天室链接的ws存进在线用户列表中的 * 问题:如何在 ...
- 【JavaScript】冒泡排序,字符串排序,数字排序
原理:是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, function bubbleClick() { var str = "50,1,4,6,9,76,43,22,2, ...