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. <4>Cocos Creator基本概念(场景树 节点 坐标 组件 )

    1.场景树 Cocos Creator是由一个一个的游戏场景组成,场景是一个树形结构,场景由 有各种层级关系的节点(下一节有具有介绍)组成: 如创建一个HelloWorld的默认项目NewProjec ...

  2. python pandas模块,nba数据处理(1)

    pandas提供了使我们能够快速便捷地处理结构化数据的大量数据结构和函数.pandas兼具Numpy高性能的数组计算功能以及电子表格和关系型数据(如SQL)灵活的数据处理能力.它提供了复杂精细的索引功 ...

  3. Sitecore CMS中如何管理默认字段值

    在Sitecore CMS中管理默认字段值. 在创建内容时,自定义默认值对内容编辑者特别有用.通过指定良好的默认值,新创建的项目可以预先填充数据,以便内容编辑者不必浪费时间一遍又一遍地填充相同的字段. ...

  4. 网关绑定命令,解决arp攻击

    一般家里的宽带都采用ADSL设备,通过固定IP地址接入Internet,但是经常会出现断网的现象,那么如何通过ARP命令绑定默认网关来解决这个问题呢? 工具/原料 ARP命令 CMD命令提示符 方法/ ...

  5. Linux基础命令---traceroute追踪路由

    traceroute       traceroute指令输出到目标主机的路由包.Traceroute跟踪从IP网络到给定主机的路由数据包.它利用IP协议的生存时间(TTL)字段,并试图在通往主机的路 ...

  6. Vuejs vm对象详解

    Vuejs vm对象详解 vue数据是怎么驱动视图的?一堆数据放在那里是不会有任何作用的,它必须通过我们的View Model(视图模型)才能操控视图. 图中的model其实就是数据,一般我们写成js ...

  7. usdt钱包开发,比特币协议 Omni 层协议 USDT

    usdt钱包开发 比特币协议 -> Omni 层协议 -> USDT USDT是基于比特币omni协议的一种代币: https://omniexplorer.info/asset/31 I ...

  8. linux java -version 和 javac -version 不一致

    我是在6 的基础上又装了一个 8. 结果java -v 和 javac -v的 一个显示 6 一个显示8 解决方式: 再次source 一下配置文件 如: source ~/.bashrc   或者  ...

  9. JustOj 1036: 习题6.11 迭代法求平方根

    题目描述 用迭代法求 .求平方根的迭代公式为: X[n+1]=1/2(X[n]+a/X[n]) 要求前后两次求出的得差的绝对值少于0.00001. 输出保留3位小数 输入 X 输出 X的平方根 样例输 ...

  10. SQL Server双机热备之后项目的FailOver自动连接

    SQL Server配置数据库镜像后,可能有朋友们会比较有疑惑,你一下搞两个数据库出来,他们的ip地址都不一样,到时候数据库切换过去了,我的数据库的连接字符串可如何是好?难道还得在代码中去控制是连接哪 ...