bzoj1565: [NOI2009]植物大战僵尸

链接

https://www.lydsy.com/JudgeOnline/problem.php?id=1565

思路

很容易的想到最大权闭合子图

但这个图是有环的

有环的地方当然是都过不去的地方

显然他所保护的地方也是过不去的

他保护的地方的保护的地方也是过不去的

等等

还有这个这一行的[1,i]也是过不去的

tarjan之后递归判一下就行了

错误

好菜欧,调试了半天

其实我一开始以为环上就有了他所保护的地方

改了之后又没想到他保护的地方的保护的地方也是不可以过去的

好菜欧

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+7,M=107,inf=0x3f3f3f3f;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,S,T,Score[M][M],id[M][M];
vector<pair<int,int> > dsr[M][M];
bool mmp[M][M];
pair<int,int> kkk[M*M];
struct node {
int u,v,nxt,cap;
}e[N];
int head[N],tot=1;
void add_edge(int u,int v,int cap) {
e[++tot].u=u;
e[tot].v=v;
e[tot].cap=cap;
e[tot].nxt=head[u];
head[u]=tot;
}
void add(int u,int v,int cap) {
add_edge(u,v,cap);
add_edge(v,u,0);
}
int dis[N];
queue<int> q;
bool bfs() {
memset(dis,-1,sizeof(dis));
q.push(S);
dis[S]=0;
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(dis[v]==-1&&e[i].cap) {
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[T]!=-1;
}
int dfs(int u,int f) {
if(u==T) return f;
int rest=f;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(dis[v]==dis[u]+1&&e[i].cap&&rest) {
int t=dfs(v,min(e[i].cap,rest));
if(!t) dis[v]=0;
e[i].cap-=t;
e[i^1].cap+=t;
rest-=t;
}
}
return f-rest;
}
int dinic() {
int ans=0;
while(bfs())
ans+=dfs(S,inf);
return ans;
}
int dfn[N],low[N],stak[N],top,cnt,vis[N],belong[N];
vector<int> BE[N];
void tarjan(int u) {
dfn[u]=low[u]=++cnt;
vis[u]=1;
stak[++top]=u;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(!e[i].cap) continue;
if(!dfn[v]) {
tarjan(v);
low[u]=min(low[u],low[v]);
} else if(vis[v]) {
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]) {
belong[0]++;
while(stak[top]!=u) {
vis[stak[top]]=0;
belong[stak[top]]=belong[0];
BE[belong[0]].push_back(stak[top]);
top--;
} top--;
vis[u]=0;
BE[belong[0]].push_back(u);
belong[u]=belong[0];
}
}
void AC(int u) {
if(mmp[kkk[u].first][kkk[u].second]) return;
for(int k=1;k<=kkk[u].second;++k) mmp[kkk[u].first][k]=1;
mmp[kkk[u].first][kkk[u].second]=1;
for(vector<pair<int,int> >::iterator it=dsr[kkk[u].first][kkk[u].second].begin();it!=dsr[kkk[u].first][kkk[u].second].end();++it)
// for(auto it : dsr[kkk[u].first][kkk[u].second])
AC(id[it->first][it->second]);
}
int main() {
n=read(),m=read();
for(int i=1,js=0;i<=n;++i) { for(int j=1;j<=m;++j) {
id[i][j]=++js;
kkk[js]=make_pair(i,j);
}}
for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) {
Score[i][j]=read();
int gs=read();
for(int k=1;k<=gs;++k) {
int x=read()+1,y=read()+1;
dsr[i][j].push_back(make_pair(x,y));
}
if(j>1)
dsr[i][j].push_back(make_pair(i,j-1));
}}
S=n*m+1,T=n*m+2;
for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) {
for(vector<pair<int,int> >::iterator it=dsr[i][j].begin();it!=dsr[i][j].end();++it) {
add(id[i][j],id[it->first][it->second],inf);
}
}}
for(int i=1;i<=n*m;++i)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=tot;i++) {
if(belong[e[i].u]==belong[e[i].v]) {
AC(e[i].u);
}
}
memset(head,0,sizeof(head));
memset(e,0,sizeof(e));
tot=1;
for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) {
if(mmp[i][j]==1) continue;
if(j!=m&&mmp[i][j+1]!=1) add(id[i][j],id[i][j+1],inf);
// for(auto it : dsr[i][j]) {
for(vector<pair<int,int> >::iterator it=dsr[i][j].begin();it!=dsr[i][j].end();++it) {
if(mmp[it->first][it->second]!=1)
add(id[it->first][it->second],id[i][j],inf);
}
}}
int sum=0;
for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) {
if(Score[i][j]>0&&!mmp[i][j]) sum+=Score[i][j];
if(mmp[i][j]==1) continue;
if(Score[i][j]>0) add(S,id[i][j],Score[i][j]);
else add(id[i][j],T,-Score[i][j]);
}}
int ans=sum-dinic();
printf("%d\n",ans);
return 0;
}

bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan的更多相关文章

  1. BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序

    题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...

  2. P2805 [NOI2009]植物大战僵尸 + 最大权闭合子图 X 拓扑排序

    传送门:https://www.luogu.org/problemnew/show/P2805 题意 有一个n * m的地图,你可以操纵僵尸从地图的右边向左边走,走的一些地方是有能量值的,有些地方会被 ...

  3. BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)

    题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...

  4. Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序

    题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:p ...

  5. BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流

    题意: 植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: (1)价值: (2)保护集合,也就是这个植物可以保护矩阵中的某些格子. 现在你是僵尸,你每次只能从(i,m) 格子 ...

  6. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  7. BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】

    题目 输入格式 输出格式 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. 输入样例 3 2 10 0 20 0 -10 0 -5 1 0 0 100 ...

  8. [bzoj1565][NOI2009]植物大战僵尸_网络流_拓扑排序

    植物大战僵尸 bzoj1565 题目大意:给你一张网格图,上面种着一些植物.你从网格的最右侧开始进攻.每个植物可以对僵尸提供能量或者消耗僵尸的能量.每个植物可以保护一个特定网格内的植物,如果一个植物被 ...

  9. [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]

    Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...

随机推荐

  1. idea上将项目上传到github

    1.下载并安装好git,然后配置git的path路径.再配置git的全局用户名和邮箱. 2.注册github账号,如果已经有github账号,则此步骤可以省略. 3.在idea中配置git,配置如下: ...

  2. spring aop:aspectj-autoproxy 配置

    经常遇到aop-aspectJ的通知不被执行的问题 解决方法:http://blog.csdn.net/qwdafedv/article/details/53005210 首先,确保配置文件都已经是正 ...

  3. JTable的模型

    2018-11-04 23:15:21开始写 模型类 import javax.swing.table.DefaultTableModel;//导入包 public class LocalTableM ...

  4. Windsor

    https://github.com/castleproject/Windsor https://github.com/castleproject/Windsor/blob/master/docs/R ...

  5. 【Redis学习之八】Redis集群:主从复制

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 redis-2.8.18 Redis集群分类: 主从复制 R ...

  6. 谈谈Groovy闭包

    A closure is a function with variables bound to a context or environment in which it executes. 概述 闭包 ...

  7. PyCharm 2017.2.3 版本在2017年9月7日发布,支持 Docker Compose

    PyCharm是由JetBrains打造的一款Python IDE.PyCharm具备用于一般IDE的功能,比如, 调试.语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制 ...

  8. js多个异步请求

    一,两个(或多个)js异步并发执行,怎么在两个AJax异步操作之后执行一个新的操作 原题来自 ES6 方法 1.Promise 包装异步ajax操作,2.定义async 函数,3.用await等待pr ...

  9. FTP搭建 共享上网 穿透内网外网

    1.ftp原理介绍 FTP只通过TCP连接,没有用于FTP的UDP组件.FTP不同于其他服务的是它使用了两个端口, 一个数据端口和一个命令端口(或称为控制端口).通常21端口是命令端口,20端口是数据 ...

  10. こだわり者いろはちゃん / Iroha's Obsession (暴力枚举)

    题目链接:http://abc042.contest.atcoder.jp/tasks/arc058_a Time limit : 2sec / Memory limit : 256MB Score ...