【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进攻. ...
随机推荐
- JDK8漫谈——代码更优雅
简介 lambda表达式,又称闭包(Closure)或称匿名方法(anonymous method).将Lambda表达式引入JAVA中的动机源于一个叫"行为参数"的模式.这种模式 ...
- DevOps知识地图实践指南
DevOps知识地图 DevOps方法论的主要来源是Agile, Lean 和TOC, 独创的方法论是持续交付. DevOps经典图书: * <DevOps实践指南> * <持续 ...
- mysql操作命令梳理(2)-alter(update、insert)
在mysql运维操作中会经常使用到alter这个修改表的命令,alter tables允许修改一个现有表的结构,比如增加或删除列.创造或消去索引.改变现有列的类型.或重新命名列或表本身,也能改变表的注 ...
- Jenkins构建自动化任务
前言 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 一.环境配置 1.切换到jenkins ...
- Jenkins部署Python项目实战
一.背景 我们工作中常用Jenkins部署Java代码,因其灵活的插件特性,例如jdk,maven,ant等使得java项目编译后上线部署一气呵成,同样对于脚本语言类型如Python上线部署,利用Je ...
- 团队项目第二周spec设计
本系统针对局域网进行联机聊天.聊天室分为服务器端和和客户端俩部分,服务器端程序主要 负责侦听客户端发来的信息,客户端需要登录到服务器端才可以实现正常的聊天功能. 1.本软件是一款局域网聊天软件,不能进 ...
- pandas(DataFrame)
DataFrame是二维数据结构,即数据以行和列的表格方式排列!特点:潜在的列是不同的类型,大小可变,标记行和列,可以对列和行执行算数运算. 其中Name,Age即为对应的Columns,序号0,1, ...
- PAT 1046 划拳
https://pintia.cn/problem-sets/994805260223102976/problems/994805277847568384 划拳是古老中国酒文化的一个有趣的组成部分.酒 ...
- Docker查看容器IP
https://segmentfault.com/q/1010000001637726 https://blog.csdn.net/sannerlittle/article/details/77063 ...
- Ajax cross domain
xhrFields:{ withCredentials:true}, https://stackoverflow.com/questions/2054316/sending-credentials-w ...