BZOJ1458士兵占领 最大流的模板题
Posted TS_Hugh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1458士兵占领 最大流的模板题相关的知识,希望对你有一定的参考价值。
我们只要把他们可以有的限制用流量限制,再用两者关系限制一下就可以开心的跑了。
#include <cstdio> #include <cstring> #include <iostream> #define r register #define N 1005 using namespace std; inline int read() { r int sum=0; r char ch=getchar(); while(ch<‘0‘||ch>‘9‘)ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) { sum=(sum<<1)+(sum<<3)+ch-‘0‘; ch=getchar(); } return sum; } int g[N][N]; struct VIA { int to,next,w; }c[N<<4]; int head[N<<1],t=1; int n,m,k; inline void add(int x,int y,int z) { c[++t].to=y; c[t].next=head[x]; head[x]=t; c[t].w=z; } int L[N],C[N],LL[N],CC[N],S,T; int deep[N<<1],q[N<<1],top,tail; inline bool bfs() { memset(deep,0,sizeof(deep)); q[1]=S; top=tail=1; deep[S]=1; while(top<=tail) { r int x=q[top++]; if(x==T)return 1; for(int i=head[x];i;i=c[i].next) if(c[i].w&&deep[c[i].to]==0) { deep[c[i].to]=deep[x]+1; q[++tail]=c[i].to; } } return 0; } inline int Min(int x,int y) { return x<y?x:y; } int dfs(int x,int v) { if(x==T||!v)return v; r int ret=0; for(r int i=head[x];i;i=c[i].next) if(c[i].w&&deep[c[i].to]==deep[x]+1) { r int f=Min(v,c[i].w); r int w=dfs(c[i].to,f); v-=w; ret+=w; c[i].w-=w; c[i^1].w+=w; if(!v)break; } if(!ret)deep[x]=-1; return ret; } inline int dinic() { r int ans=0; while(bfs())ans+=dfs(S,0x7f7f7f7f); return ans; } int main() { r int ans=0; n=read(),m=read(),k=read(); for(r int i=1;i<=n;++i)L[i]=read(),LL[i]=m,ans+=L[i]; for(r int i=1;i<=m;++i)C[i]=read(),CC[i]=n,ans+=C[i]; for(r int i=1,x,y;i<=k;++i)x=read(),y=read(),g[x][y]=1,--LL[x],--CC[y]; for(r int i=1;i<=n;++i) if(L[i]>LL[i]) { printf("JIONG!\n"); return 0; } for(r int i=1;i<=m;++i) if(C[i]>CC[i]) { printf("JIONG!\n"); return 0; } S=n+m+1,T=m+n+2; for(r int i=1;i<=n;++i) for(r int j=1;j<=m;++j) if(!g[i][j]) add(i,j+n,1),add(j+n,i,0); for(r int i=1;i<=n;++i) add(S,i,L[i]),add(i,S,0); for(r int i=1;i<=m;++i) add(i+n,T,C[i]),add(T,n+i,0); ans-=dinic(); printf("%d\n",ans); }
以上是关于BZOJ1458士兵占领 最大流的模板题的主要内容,如果未能解决你的问题,请参考以下文章