一上来以为是裸的最大权闭合子图,上来就dinic
…然后没过样例。不得不说样例还是非常良心的给了一个强连通分量,要不然就WA的生活不能自理了
然后注意到有一种特殊情况:每个植物向他保护的植物连边(包括被其挡在后面的),当植物的保护范围连成一个强连通分量时,这个强连通分量上的植物以及从这个强连通分量连出去的植物,都不会在任何情况下被攻击
如下图:

12345所形成的强连通分量不会被攻击,所以它所延伸出来的植物也不会被攻击,即图上所有点都不会被攻击
对于这种情况,用tarjan缩点,对于每个缩后的点记录一个size,对于所有 \(size[belong[u]]>1\) 的点向外dfs,记录不会被攻击到的点即可
删去所有不会被攻击到的点及其所连的边之后,跑最大权闭合子图。
具体如下:

  • s点向所有正权点连边,流量为点权;所有负权点向t连边,流量为负点权(即正数!)
  • 对于所有有依赖关系的点,由被保护的植物向保护植物连边(也就是把上面为tarjan建的图所有有向边反过来),也就是最大权闭合子图中的向其依赖点连边,流量为inf

\[ ans=\sum 正权点点权-最小割 \]

  • 割的意义:与原点相连的点表示被选择,与汇点相连的点表示不选
  • S连向正权点的边被割:说明正权点被划入T侧,代表不选,收益被扣除
  • 负权点连向T的边被割:说明负权点被划入S侧,代表被选,要承受惩罚
  • 有依赖关系的点之间无法被割:a-->b,则如果a在S侧那b也一定在S侧

莫名跑的慢,大概是写丑了

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
const int E=1000005,inf=1e9,N=55,P=1005;
int n,m,sum,h[E],cnt,le[E],s,t,v[N][N],dfn[P],tot,low[P],st[P],top,con,bl[P],si[P];
bool in[P];
vector<pair<int,int> >vec;
struct qwe
{int ne,to,va;
}e[E<<1];
int read()
{int r=0,f=1;char p=getchar();while(p>'9'||p<'0'){if(p=='-')f=-1;p=getchar();}while(p>='0'&&p<='9'){r=r*10+p-48;p=getchar();}return r*f;
}
void addd(int u,int v)
{//cout<<u<<" "<<v<<endl;vec.push_back(make_pair(u,v));cnt++;e[cnt].ne=h[u];e[cnt].to=v;h[u]=cnt;
}
void add(int u,int v,int w)
{cnt++;e[cnt].ne=h[u];e[cnt].to=v;e[cnt].va=w;h[u]=cnt;
}
void ins(int u,int v,int w)
{//cout<<u<<" "<<v<<" "<<w<<endl;add(u,v,w);add(v,u,0);
}
bool bfs()
{queue<int>q;memset(le,0,sizeof(le));le[s]=1;q.push(s);while(!q.empty()){int u=q.front();q.pop();for(int i=h[u];i;i=e[i].ne)if(e[i].va>0&&!le[e[i].to]){le[e[i].to]=le[u]+1;q.push(e[i].to);}}return le[t];
}
int dfs(int u,int f)
{if(u==t||!f)return f;int us=0;for(int i=h[u];i&&us<f;i=e[i].ne)if(le[e[i].to]==le[u]+1&&e[i].va>0){int t=dfs(e[i].to,min(e[i].va,f-us));e[i].va-=t;e[i^1].va+=t;us+=t;}if(!us)le[u]=0;return us;
}
int dinic()
{int re=0;while(bfs())re+=dfs(s,inf);return re;
}void dfs(int u)
{in[u]=1;for(int i=h[u];i;i=e[i].ne)if(!in[e[i].to]) dfs(e[i].to);
}void tarjan(int u)
{//cout<<u<<endl;dfn[u]=low[u]=++tot;in[u]=1;st[++top]=u;for(int i=h[u];i;i=e[i].ne){if(!dfn[e[i].to]){tarjan(e[i].to);low[u]=min(low[u],low[e[i].to]);}else if(in[e[i].to])low[u]=min(low[e[i].to],dfn[e[i].to]);}if(dfn[u]==low[u]){con++;while(st[top]!=u){in[st[top]]=0;bl[st[top--]]=con;si[con]++;}in[st[top]]=0;bl[st[top--]]=con;si[con]++;}
}
int main()
{n=read(),m=read();t=n*m+1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){v[i][j]=read();int id=(i-1)*m+j,w=read(); //cout<<sor<<" "<<w<<endl;if(j>1)addd(id,id-1);while(w--){int x=read()+1,y=read()+1;addd(id,(x-1)*m+y);}}//cout<<"ok"<<endl;for(int i=1;i<=n*m;i++)if(!dfn[i])tarjan(i);//,cout<<i<<endl;for(int i=1;i<=n*m;i++)if(si[bl[i]]>1&&!in[i])dfs(i);cnt=1;memset(h,0,sizeof(h));memset(e,0,sizeof(e));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if(!in[(i-1)*m+j]){int x=(i-1)*m+j;if(v[i][j]>=0)ins(s,x,v[i][j]),sum+=v[i][j];elseins(x,t,-v[i][j]);}for(int i=0;i<vec.size();i++)if(!in[vec[i].first]&&!in[vec[i].second])ins(vec[i].second,vec[i].first,inf);//cout<<"ok"<<endl;printf("%d\n",sum-dinic());return 0;
}

转载于:https://www.cnblogs.com/lokiii/p/8178805.html

bzoj 1565 [NOI2009]植物大战僵尸【tarjan+最大权闭合子图】相关推荐

  1. BZOJ 1565 Luogu P2805 [NOI2009]植物大战僵尸 (Tarjan判环、最小割)

    我: "立个flag 14点之前调完这题" 洛谷AC时间: 2019-06-24 14:00:16 实力打脸... 网络流板子从来写不对系列 题目链接: (BZOJ) https: ...

  2. BZOJ 4873 [Shoi2017]寿司餐厅 | 网络流 最大权闭合子图

    链接 BZOJ 4873 题解 当年的省选题--还记得蒟蒻的我Day1 20分滚粗-- 这道题是个最大权闭合子图的套路题.严重怀疑出题人就是先画好了图然后照着图编了个3000字的题面.和我喜欢的妹子当 ...

  3. 【BZOJ】1497: [NOI2006]最大获利 最大权闭合子图或最小割

    [题意]给定n个点,点权为pi.m条边,边权为ci.选择一个点集的收益是在[点集中的边权和]-[点集点权和],求最大获利.n<=5000,m<=50000,0<=ci,pi<= ...

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

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

  5. 【bzoj1565】[NOI2009]植物大战僵尸 【网络流】【最大权闭合子图】

    题解:可以看出每个格子有一些前驱,只有前驱都被消灭了才能走到这里.因为要求最大的权值和,所以我们可以用最大权闭合子图来求解这题.最大权闭合子图点这里! 然后让蒟蒻讲一讲自己掉的坑. 首先,根据WYC大 ...

  6. BZOJ 1565 [NOI2009]植物大战僵尸

    title: 'BZOJ 1565 [NOI2009]植物大战僵尸' categories: BZOJ date: 2016-3-20 9:30:00 tags: [最小割] Description ...

  7. BZOJ1565:[NOI2009]植物大战僵尸——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1565 https://www.luogu.org/problemnew/show/P2805 Pla ...

  8. 网络流 - 最大权闭合子图 [NOI2009]植物大战僵尸

    算法思想概述 本题是一道最大权闭合子图模型,应用的算法为最大流(BFS增广即可),定理为最大流最小割定理,辅助算法为拓扑排序. 问题初始建模 首先我们我建立图论模型,把每个植物当做一个顶点,植物携带的 ...

  9. 最大权闭合子图(最小割)

    最大权闭合子图(最大流最小割) •参考资料 [1]最大权闭合子图 •权闭合子图 存在一个图的子图,使得子图中的所有点出度指向的点依旧在这个子图内,则此子图是闭合子图. 在这个图中有8个闭合子图:∅,{ ...

最新文章

  1. python判断列表list中的内容、数值是否全部都大于某一个阈值(threshold)、如果数值都大于某一个阈值(threshold)则跳出循环
  2. 赵胜男:数据思维,让我的科研和志愿服务动力十足 | 提升之路系列(十二)...
  3. iOS 模仿微信的照片选择器
  4. 【OkHttp】OkHttp 源码分析 ( 网络框架封装 | OkHttp 4 迁移 | OkHttp 建造者模式 )
  5. 5.2 matlab多项式计算(多项式的四则运算、求导、求值、求根)
  6. Synchronize对String加锁解决
  7. 京东产品负责人:数据如何高效驱动供应链?
  8. 并查集求欧拉回路/通路
  9. PHP面向对象 封装与继承
  10. getSystemService
  11. (36)System Verilog线程并行执行(fork-join)
  12. 如何在java输入_怎么在java中编写输入语句?
  13. 计算机机房综合布线方案,计算机网络设备施工方案(不含综合布线)(word版)
  14. Layui实现Eharts图表
  15. 【python爬虫】第11章——scrapy框架持久化存储
  16. 推荐 21 款博主常用 Windows 软件
  17. 【RFID】阅读器和应答器之间的电感耦合
  18. javaGUI学习1:GUI框架,工具介绍
  19. ccfcsp-20190301小中大-JAVA语言
  20. Instagram 图谱 API

热门文章

  1. WebSocket 实现原理
  2. controller属于哪一层_五种皮肤类型,那你属于哪一种,你知道吗?
  3. python简介pdf_Py之pdfkit:python的库之pdfkit简介、安装、使用方法详细攻略
  4. ctfshow-萌新-web9( 利用命令执行漏洞读取网站敏感文件)
  5. 领酌酒业:一文阅尽酱香酒
  6. 一边学,一边写出的人工智能教程(一)
  7. Java二十三设计模式之------迭代子模式
  8. mybatis如何在控制台打印执行的sql语句
  9. EnjoyCSS – 在线的,先进的 CSS3 代码生成器
  10. ECSHOP2.7.3删除后台左侧菜单中的云服务中心