【bzoj1565】 NOI2009—植物大战僵尸
http://www.lydsy.com/JudgeOnline/problem.php?id=1565 (题目链接)
题意
给出$n*m$的棋盘,僵尸攻击每个格子可以获得$v$的分数,每个格子又会保护一些别的格子,想攻击被保护的格子必须先攻击没被保护的格子。问获得的最大分数。
Solution
建图,被保护的点向保护它的点连边。显然,环上的点是不可能被击败的,我们Tarjan以后把环上的点以及指向环的点扔掉。剩下的点做最大权闭合子图就好了。
这里扔掉不是真的扔掉,只要不让S和T与之相连就好了。
细节
数组大小
代码
// bzoj1565
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf (1ll<<30)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std; const int maxn=100010,maxm=1000010;
int head[maxn],d[maxn],n,m,cnt,ans,tot,S,T;
int size[maxn],dfn[maxn],low[maxn],bel[maxn],vis[maxn],val[maxn],st[maxn],DFN,scc,top;
struct edge {int to,next,w;}e[maxm];
pair<int,int> E[maxm]; namespace Dinic {
void link(int u,int v,int w) {
e[++cnt]=(edge){v,head[u],w};head[u]=cnt;
e[++cnt]=(edge){u,head[v],0};head[v]=cnt;
}
bool bfs() {
for (int i=S;i<=T;i++) d[i]=-1;
queue<int> q;q.push(S);d[S]=0;
while (!q.empty()) {
int x=q.front();q.pop();
for (int i=head[x];i;i=e[i].next)
if (e[i].w && d[e[i].to]<0) d[e[i].to]=d[x]+1,q.push(e[i].to);
}
return d[T]>0;
}
int dfs(int x,int f) {
if (x==T || f==0) return f;
int w,used=0;
for (int i=head[x];i;i=e[i].next) if (e[i].w && d[e[i].to]==d[x]+1) {
w=dfs(e[i].to,min(e[i].w,f-used));
used+=w,e[i].w-=w;e[i^1].w+=w;
if (used==f) return used;
}
if (!used) d[x]=-1;
return used;
}
int main() {
int flow=0;
while (bfs()) flow+=dfs(S,inf);
return flow;
}
} void link(int u,int v) {e[++cnt]=(edge){v,head[u]};head[u]=cnt;}
void Tarjan(int x) {
st[++top]=x;dfn[x]=low[x]=++DFN;
for (int i=head[x];i;i=e[i].next) {
if (!dfn[e[i].to]) {
Tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if (!bel[e[i].to]) low[x]=min(low[x],dfn[e[i].to]);
}
if (dfn[x]==low[x]) {
scc++;
for (;st[top]!=x;top--) bel[st[top]]=scc,size[scc]++;
bel[st[top--]]=scc;size[scc]++;
}
}
bool dfs(int x) {
if (vis[x]) return size[x];
if (size[x]>1) size[x]=0;
vis[x]=1;
for (int i=head[x];i;i=e[i].next) if (e[i].w) size[x]&=dfs(e[i].to);
return size[x];
}
int main() {
scanf("%d%d",&n,&m);
for (int i=0;i<n;i++)
for (int x,y,t,j=1;j<=m;j++) {
scanf("%d%d",&val[i*m+j],&t);
for (int k=1;k<=t;k++) scanf("%d%d",&x,&y),link(x*m+y+1,i*m+j);
if (j<m) link(i*m+j,i*m+j+1);
}
for (int i=1;i<=n*m;i++) if (!dfn[i]) Tarjan(i);
for (int i=1;i<=n*m;i++)
for (int j=head[i];j;j=e[j].next)
if (bel[i]!=bel[e[j].to]) E[++tot]=pair<int,int>(bel[i],bel[e[j].to]);
memset(head,0,sizeof(head));cnt=1;
for (int i=1;i<=tot;i++) Dinic::link(E[i].first,E[i].second,inf);
for (int i=1;i<=scc;i++) if (!vis[i]) dfs(i);
S=0,T=n*m+1;
for (int i=1;i<=n*m;i++) if (size[bel[i]]) {
if (val[i]>=0) Dinic::link(S,bel[i],val[i]),ans+=val[i];
else Dinic::link(bel[i],T,-val[i]);
}
ans=max(0,ans-Dinic::main());
printf("%d",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]植物大战僵尸
1.题意:有一些点,点与点之间有保护关系,每个点都有一个权值,求能获得的最大值 2.分析:裸的最大权闭合图,用网络流进行求解,然后我们发现点与点之间的保护关系可能构成环,这样网络流是无法处理的,然后我 ...
- 【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进攻. ...
随机推荐
- NB-IOT_BC95_B5常用AT指令集
.AT+<cmd>=? 测试命令,用于向模块询问支持的设置项目. .AT+<cmd>? 读取命令,用于让模块上报某个命令代表的设置项当前的值. .AT+<cmd>= ...
- ASS字幕制作
虽然不常做视频,但正因为是偶尔用到,所以总是记不牢,特此笔记. Name 字体名称?Fontname 字体名称(\fn冬青黑体简体中文 W3)(\fnVogueSans)(例:\N{\fn冬青黑体简体 ...
- cross-env简介
是什么 运行跨平台设置和使用环境变量的脚本 出现原因 当您使用NODE_ENV =production, 来设置环境变量时,大多数Windows命令提示将会阻塞(报错). (异常是Windows上的B ...
- ZJOI2008 生日聚会Party
对于任意连续区间的限制,可以转化为以i结尾的所有区间的限制.这个转换在昨天的后缀自动机题也有用到,因此将其命名为区后变换.稍加分析后,我们记录以i结尾任意区间最大差即可进行DP转移.这个转换同时也创造 ...
- 第二次作业 对VC++6.0编译软件的评价
首先这个软件伴随着我们很长时间了,它是我们一上大学最先接触的,也是应用相当多的一个软件,其实在最初的时候,我对编译软件的理解非常有限,觉得它能实现一个代码的功能十分神奇的一件事情,虽然彼时我们写的代码 ...
- SCRUM 12.20
以下为我们爬虫遇到问题的报告 我们团队的m2阶段原本计划是爬取美团的信息以支持我们的app对比功能,但在这一阶段遇到很多问题,主要表现如下: 美团反爬机制: 由于我们团队人员在事先并不知道美团具有反爬 ...
- 第三个sprint冲刺第三阶段
公测版:
- GCP试用到期再申请
目标 GCP的免费试用到期了.网传可以续用,看了教程,记录下来. 法一 应该可以直接用一个新gmail账号的.这个方法的难点可能在于注册新账号有门槛.我有一个很久以前注册过的,试着找回了密码,登入GC ...
- 业务-----添加Service常用逻辑
1.参数不能为空 /** * 添加人员时判断是否字段全部传值 * @param request * @return */ private Boolean checkClientByCols(Clien ...
- 如何使用grep 等命令快速的在日志中找到自己需要的内容
虽然使用linux也有好几年了,但是服务器端开发的活儿正经来算才干不到一年. 一直没有需求和机会会去花大量的时间排查日志啥的,直到我摊上了大事t t,写的代码在线上出了bug需要排查问题. grep可 ...