[BZOJ]1565: [NOI2009]植物大战僵尸 Tarjan+最小割(最大权闭合子图)
来源:互联网 发布:周哥k101淘宝店 编辑:程序博客网 时间:2024/05/06 06:01
Description
题解:
经典的最大权闭合子图模型,不会的可以去网上查找相关资料,挺简单的。这道题呢,对于植物i可以保护植物j,我们可以建一条j->i的有向边(注意同一行相邻2个植物也有保护关系),然后跑一次Tarjan,因为在一个环中的植物我们是不能选到的,对于这些不能选到的植物,我的处理方法是将他们的权值看做负无穷,然后其他的按照最大权闭合子图搞就行了。
代码:
#include<cstdio>#include<cstring>#include<queue>#include<iostream>#include<algorithm>using namespace std;const int inf=2147483647;const int Maxn=35;const int Max=910;struct Edge1{int y,next;}E[400000];struct Edge2{int y,d,next;}e[2110000];int score1[Maxn][Maxn],score2[Max],num[Maxn][Maxn],z=0;int n,m;int last[Max],len=1;int Last[Max],Len=0;int dfn[Max],low[Max],id=0,bel[Max],cnt=0,sta[Max],top=0,p[Max];bool in[Max],vis[Max],hh[Max][Max];void ins(int x,int y,int d){ int t=++len; e[t].y=y;e[t].d=d; e[t].next=last[x];last[x]=t;}void addedge(int x,int y,int d){ins(x,y,d);ins(y,x,0);}void Ins(int x,int y){ int t=++Len; E[t].y=y;E[t].next=Last[x];Last[x]=t;}void Tarjan(int x){ low[x]=dfn[x]=++id; sta[++top]=x;in[x]=true; for(int i=Last[x];i;i=E[i].next) { int y=E[i].y; if(!dfn[y])Tarjan(y),low[x]=min(low[x],low[y]); else if(in[y])low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { int i;cnt++; do { i=sta[top--]; bel[i]=cnt; p[cnt]++; in[i]=false; }while(i!=x); }}queue<int>q;int h[Max],st,ed;bool bfs(){ memset(h,0,sizeof(h));h[st]=1; q.push(st); while(!q.empty()) { int x=q.front();q.pop(); for(int i=last[x];i;i=e[i].next) if(e[i].d&&!h[e[i].y])h[e[i].y]=h[x]+1,q.push(e[i].y); } return h[ed];}int dfs(int x,int f){ if(x==ed)return f; int s=0,t; for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(h[y]==h[x]+1&&e[i].d&&s<f) { t=dfs(y,min(f-s,e[i].d)); s+=t;e[i^1].d+=t;e[i].d-=t; } } if(s==0)h[x]=0; return s;}int main(){ int ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) num[i][j]=++z; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int k; scanf("%d%d",&score1[i][j],&k); for(int l=1;l<=k;l++) { int x,y; scanf("%d%d",&x,&y);x++;y++; Ins(num[x][y],num[i][j]); hh[num[x][y]][num[i][j]]=true; } if(j>1&&!hh[num[i][j-1]][num[i][j]])Ins(num[i][j-1],num[i][j]); } for(int i=1;i<=z;i++)if(!dfn[i])Tarjan(i); st=z+1;ed=z+2; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { int x=num[i][j]; if(p[bel[x]]>1)addedge(x,ed,inf); else if(score1[i][j]<0)addedge(x,ed,-score1[i][j]); else ans+=score1[i][j],addedge(st,x,score1[i][j]); memset(vis,false,sizeof(vis));vis[x]=true; for(int l=Last[x];l;l=E[l].next) { int y=E[l].y; if(vis[y])break;vis[y]=true; addedge(x,y,inf); } } while(bfs())ans-=dfs(st,inf); printf("%d",ans);}
阅读全文
1 0
- [BZOJ]1565: [NOI2009]植物大战僵尸 Tarjan+最小割(最大权闭合子图)
- bzoj 1565: [NOI2009]植物大战僵尸 (最大权闭合子图+tarjan+拓扑序)
- bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合子图+拓扑排序
- [省选前题目整理][BZOJ 1565][NOI 2009]植物大战僵尸(最小割+最大权闭合子图建模)
- bzoj 1565 植物大战僵尸【最大权闭合子图】
- BZOJ 1565 NOI2009 植物大战僵尸 最大权闭合图+拓扑排序
- [BZOJ1565][NOI2009]植物大战僵尸(最大权闭合子图)
- BZOJ 1565 植物大战僵尸(最大权闭合子图+拓扑排序)
- NOI2009 植物大战僵尸 最大权闭合图
- 【XSY1996】【BZOJ1565】【NOI2009】植物大战僵尸 网络流 最大权闭合子图
- [BZOJ1565][NOI2009]植物大战僵尸(tarjan+最小割)
- 【bzoj1565】[NOI2009]植物大战僵尸 最大权闭合图+拓扑排序
- 【BZOJ1565】[NOI2009]植物大战僵尸【最大权闭合图】【拓扑排序】
- bzoj1565: [NOI2009]植物大战僵尸 最小割
- bzoj 1497(最小割,最大权闭合子图)
- 【NOI2009T4】植物大战僵尸-最大权闭合子图+拓补排序
- bzoj 1565: [NOI2009]植物大战僵尸
- BZOJ 1565: [NOI2009]植物大战僵尸
- 架构师之路-一张图认识jvm内存
- 目录处理命令mkdir
- Mark一个网址
- 如何合并CSS两个字体文件
- C++指针和引用的区别与联系
- [BZOJ]1565: [NOI2009]植物大战僵尸 Tarjan+最小割(最大权闭合子图)
- 高精度加减乘法模板
- 深度学习和自然语言处理的应用和脉络2-复杂模型,最大熵-隐马尔科夫模型-条件随机场
- < 笔记 > DOM
- onTouch onTouchEvent 与 onClick三者调用先后分析
- Ubuntu16.04配置ADB调试环境
- 破解IDEA2017
- iOS11 导航栏按钮位置问题的解决------新
- javaweb接口安全校验预备知识——spring 拦截器interceptor的使用