BZOJ1565: [NOI2009]植物大战僵尸
来源:互联网 发布:矩阵论第二版答案徐仲 编辑:程序博客网 时间:2024/05/02 00:18
题目链接
【题目大意】
给定n*m大小的地图,每块有一种植物,每种植物两个功能:
①:吃掉该植物可获得x点收益,可正可负;
②:可保护若干块地上的植物。
任何一个点的植物存活时,它左侧的所有植物都无法被攻击。
求最大获利值。
【分析】
由题意易知,想获得某点的植物的收益,可能有先决条件并且该条件必须满足,即为最大权闭合图。
但此题有特殊的情况:环。当出现环时,环上任意一点都不可取。
所以就要去环。
如何去环呢!??发现我们只需要标记可选取的点就可以了,而且建图时也是有向边,所以用拓扑排序~
但是做拓扑时又有一个问题,建边时是从被保护点–>保护点,但做拓扑显然需要反过来做。这个也好解决,网络流建边时偶数边为正向边,奇数边为反向边,沿反向边更新就好了。
接下来可以选择重新建图,也可以直接在BFS中加限制条件。(我比较懒,所以写的加限制条件。)
【代码】
#include <cstdio>#include <iostream>#include <queue>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#define N 605#define M 723605#define INF 1000000001using namespace std;typedef long long ll;typedef pair<ll,ll> pa;int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*f;}int n,m,cnt=1,S,T,ans;int b[M],p[N],nextedge[M],w[M],cur[N];int Level[N],a[N],in[N];bool Not_Pro[N];void Add(int x,int y,int z){ cnt++; b[cnt]=y; nextedge[cnt]=p[x]; p[x]=cnt; w[cnt]=z;}void Anode(int x,int y,int z){ Add(x,y,z);Add(y,x,0);in[x]++;}void Input_Init(){ n=read();m=read();T=n*m+1; for(int i=1;i<=n*m;i++) { static int x,y,xx,yy; a[i]=x=read(); if(x>0) Anode(0,i,x); else Anode(i,T,-x); y=read(); while(y--) { xx=read(),yy=read(); Anode(xx*m+yy+1,i,INF); } if(i%m) Anode(i,i+1,INF); }}void Top_Sort(){ queue<int>q; for(int i=1;i<=T;i++) if(!in[i]) q.push(i); while(!q.empty()) { int k=q.front();q.pop(); Not_Pro[k]=1;if(a[k]>0) ans+=a[k]; for(int i=p[k];i;i=nextedge[i]) if(i&1) { int v=b[i];in[v]--; if(!in[v]) q.push(v); } }}bool Bfs(){ queue<int>q; q.push(S); for(int i=0;i<=T;i++) Level[i]=0; Level[S]=1; while(!q.empty()) { int k=q.front();q.pop(); for(int i=p[k];i;i=nextedge[i]) { int v=b[i],f=w[i]; if(!Level[v]&&f&&Not_Pro[v]) { Level[v]=Level[k]+1; q.push(v); } } } return Level[T];}int Dfs(int x,int maxf){ if(x==T||!maxf) return maxf; int rtn=0; for(int i=cur[x];i&&maxf>rtn;i=nextedge[i]) { int v=b[i],f=w[i]; if(Level[v]==Level[x]+1&&f) { f=Dfs(v,min(maxf-rtn,f)); w[i]-=f;w[i^1]+=f; if(w[i]>0) cur[x]=i; rtn+=f; } } if(!rtn) Level[x]=0; return rtn;}void Dinic(){ while(Bfs()) { for(int i=0;i<=T;i++) cur[i]=p[i]; ans-=Dfs(S,INF); } printf("%d\n",ans);}int main(){ Input_Init(); Top_Sort(); Dinic(); return 0;}
0 0
- bzoj1565【NOI2009】植物大战僵尸
- 【bzoj1565】[NOI2009]植物大战僵尸
- BZOJ1565: [NOI2009]植物大战僵尸
- 【NOI2009】bzoj1565 植物大战僵尸
- bzoj1565: [NOI2009]植物大战僵尸
- bzoj1565: [NOI2009]植物大战僵尸
- BZOJ1565: [NOI2009]植物大战僵尸
- bzoj1565: [NOI2009]植物大战僵尸 最小割
- BZOJ1565——[NOI2009]植物大战僵尸
- [题解]bzoj1565(NOI2009)植物大战僵尸
- 【bzoj1565】【NOI2009】【植物大战僵尸】【拓扑排序+最小割】
- Bzoj1565:[NOI2009]植物大战僵尸:拓扑排序+网络流
- BZOJ1565: [NOI2009]植物大战僵尸 最小割 拓扑排序
- [BZOJ1565][NOI2009]植物大战僵尸(tarjan+最小割)
- [BZOJ1565][NOI2009]植物大战僵尸-拓扑排序-网络流
- [NOI2009]植物大战僵尸
- [noi2009]植物大战僵尸
- 【NOI2009】植物大战僵尸
- Build.gradle 详细配置说明
- mysql版本导致的hibernate 方言问题
- 使用BusyBox制作嵌入式Linux根文件系统
- Hadoop和eclipse进行关联
- 中科断网神器的功能及界面
- BZOJ1565: [NOI2009]植物大战僵尸
- Python3 方法整理
- HTTP 请求
- 缓冲字符流
- soui介绍(转载)
- 博为峰Java技术题 ——JavaSE Java Swing在顶层容器中添加菜单栏Ⅰ
- apache单ip多域名多目录配置
- 【JAVA秒会技术之玩搞定GC】GC算法与种类
- 运维演进正确之道-ITIL+DevOps双态运维