[BZOJ1565]植物大战僵尸
Posted jefflyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1565]植物大战僵尸相关的知识,希望对你有一定的参考价值。
如果$x$可以攻击$y$,那么选了$y$就一定要选$x$,并且选了$x$就一定要选$x$右边的格子,格子还有权值,这就是最大权闭合子图的模型了,但是注意到图中可能存在环,直接拓扑排序忽略环即可
#include<stdio.h> #include<string.h> const int inf=100000000; int min(int a,int b){return a<b?a:b;} namespace g1{ int h[610],nex[600010],to[600010],d[610],q[600010],M,n; bool ok[610]; void add(int a,int b){ M++; to[M]=b; d[b]++; nex[M]=h[a]; h[a]=M; } void sort(){ int head,tail,x,i; head=1; tail=0; for(i=1;i<=n;i++){ if(d[i]==0){ tail++; q[tail]=i; ok[i]=1; } } while(head<=tail){ x=q[head]; head++; for(i=h[x];i;i=nex[i]){ d[to[i]]--; if(d[to[i]]==0){ tail++; q[tail]=to[i]; ok[to[i]]=1; } } } } } namespace g2{ int h[610],cur[610],to[2000010],nex[2000010],cap[2000010],dis[610],q[2000010],M=1,S,T; void add(int a,int b,int c){ M++; to[M]=b; cap[M]=c; nex[M]=h[a]; h[a]=M; M++; to[M]=a; cap[M]=0; nex[M]=h[b]; h[b]=M; } bool bfs(){ int head,tail,x,i; memset(dis,-1,sizeof(dis)); head=tail=1; q[1]=S; dis[S]=0; while(head<=tail){ x=q[head]; head++; for(i=h[x];i;i=nex[i]){ if(cap[i]&&dis[to[i]]==-1){ dis[to[i]]=dis[x]+1; if(to[i]==T)return 1; tail++; q[tail]=to[i]; } } } return 0; } int dfs(int x,int flow){ if(x==T)return flow; int i,f; for(i=cur[x];i;i=nex[i]){ if(cap[i]&&dis[to[i]]==dis[x]+1){ f=dfs(to[i],min(flow,cap[i])); if(f){ cap[i]-=f; cap[i^1]+=f; if(cap[i])cur[x]=i; return f; } } } dis[x]=-1; return 0; } int dicnic(){ int ans,tmp; ans=0; while(bfs()){ memcpy(cur,h,sizeof(h)); while(tmp=dfs(S,inf))ans+=tmp; } return ans; } } int n,m,v[610]; int tr(int x,int y){return(x-1)*m+y;} using namespace g1; int main(){ int i,j,t,x,y,sum; scanf("%d%d",&::n,&m); g1::n=::n*m; for(i=1;i<=g1::n;i++){ scanf("%d%d",v+i,&t); while(t--){ scanf("%d%d",&x,&y); add(i,tr(x+1,y+1)); } } for(i=1;i<=::n;i++){ for(j=1;j<m;j++)add(tr(i,j+1),tr(i,j)); } sort(); using g2::S; using g2::T; using g2::add; using g1::n; S=n+1; T=n+2; sum=0; for(x=1;x<=n;x++){ if(ok[x]){ if(v[x]>0){ sum+=v[x]; add(S,x,v[x]); }else if(v[x]<0) add(x,T,-v[x]); for(i=h[x];i;i=nex[i]){ if(ok[to[i]])add(to[i],x,inf); } } } printf("%d",sum-g2::dicnic()); }
以上是关于[BZOJ1565]植物大战僵尸的主要内容,如果未能解决你的问题,请参考以下文章