[BZOJ1412]ZJOI2009狼和羊的故事|最小割

来源:互联网 发布:网络信息安全员证书 编辑:程序博客网 时间:2024/05/06 05:51

源向羊连边,汇向狼连边,羊向狼和空地连边,狼向空地和羊连边,空地向狼、羊和空地连边,答案就是最小割(最大流)。。

#include<cstdio>#include<iostream>#include<memory.h>#define N 105#define inf 9999999using namespace std;struct edge{int e,f,next;}ed[10*N*N];int n,m,i,j,nd,x,ne=1,a[N*N],d[N*N],u[N*N],que[N*N],map[N][N];void add(int s,int e,int f){ed[++ne].e=e;ed[ne].f=f;ed[ne].next=a[s];a[s]=ne;}bool bfs(int s,int t){int head=1,tail=1,get,i,j;for (i=0;i<=nd;i++) u[i]=d[i]=0;que[1]=s;u[s]=1;while (head<=tail){get=que[head++];for (j=a[get];j;j=ed[j].next)if (ed[j].f&&!u[ed[j].e]){d[ed[j].e]=d[get]+1;u[ed[j].e]=1;que[++tail]=ed[j].e;}}return d[t]!=0;}int extend(int x,int minf,int t){if (x==t) return minf;int f=minf,del,j;for (j=a[x];j;j=ed[j].next)if (ed[j].f&&d[x]+1==d[ed[j].e]){del=extend(ed[j].e,min(minf,ed[j].f),t);ed[j].f-=del;ed[j^1].f+=del;minf-=del;if (!minf) break;}if (f==minf) d[x]=0;return f-minf;}int dinic(int s,int t){int ans=0;while (bfs(s,t)) ans+=extend(s,inf,t);return ans;}int main(){freopen("1412.in","r",stdin);scanf("%d%d",&n,&m);memset(a,0,sizeof(a));nd=n*m+1;for (i=1;i<=n;i++)for (j=1;j<=m;j++){x=(i-1)*m+j;scanf("%d",&map[i][j]);if (map[i][j]==1) add(0,x,inf),add(x,0,0);if (map[i][j]==2) add(x,nd,inf),add(nd,x,0);if (i-1/*&&map[i-1][j]!=map[i][j]*/) add(x,x-m,1),add(x-m,x,1); if (j-1/*&&map[i][j-1]!=map[i][j]*/) add(x,x-1,1),add(x-1,x,1);}printf("%d",dinic(0,nd));}


0 0