标签:
1 #include<bits/stdc++.h> 2 #define N 10233 3 #define inf 2147483647 4 #define rep(i,l,r) for(int i=l;i<=r;i++) 5 using namespace std; 6 const int x[4]={1,-1,0,0}; 7 const int y[4]={0,0,1,-1}; 8 struct node{ 9 int to,next,w; 10 }e[500000]; 11 int head[N],m,n,nx,ny,ans,dis[N],T,tot=1,cnt,num[110][110],mp[110][110]; 12 inline void ins(int u,int v,int w) { 13 e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w; 14 } 15 inline void insert(int u,int v,int w) { 16 ins(u,v,w); ins(v,u,0); 17 } 18 inline bool bfs(){ 19 memset(dis,-1,sizeof(dis)); queue<int>q; q.push(0); dis[0]=0; 20 while(!q.empty()) { 21 int x=q.front(); q.pop(); 22 for(int k=head[x];k;k=e[k].next) 23 if(dis[e[k].to]<0 && e[k].w>0) { 24 dis[e[k].to]=dis[x]+1; q.push(e[k].to); 25 } 26 } 27 if(dis[T]>0) return 1;else return 0; 28 } 29 int find(int x,int low){ 30 if(x==T) return low; 31 int delta=low,now; 32 for(int k=head[x];k;k=e[k].next) 33 if(e[k].w>0 && dis[e[k].to]==dis[x]+1){ 34 now=find(e[k].to,min(e[k].w,delta)); 35 e[k].w-=now; e[k^1].w+=now; delta-=now; 36 if(!delta) return low; 37 } 38 dis[x]=-1; 39 return low-delta; 40 } 41 int main () { 42 scanf("%d%d",&n,&m); T=n*m+1; 43 rep(i,1,n) rep(j,1,m) num[i][j]=++cnt; 44 rep(i,1,n) rep(j,1,m) { 45 scanf("%d",&mp[i][j]); 46 if(mp[i][j]==1) insert(0,num[i][j],inf);else if(mp[i][j]==2) insert(num[i][j],T,inf); 47 for(int k=0;k<4;k++) 48 { 49 int nowx=i+x[k],nowy=j+y[k]; 50 if(nowx<1||nowx>n||nowy<1||nowy>m||mp[i][j]==2)continue; 51 if(mp[i][j]!=1||mp[nowx][nowy]!=1) 52 insert(num[i][j],num[nowx][nowy],1); 53 } 54 } 55 while(bfs()) ans+=find(0,inf); 56 printf("%d",ans); 57 }
从源点向所有狼连一条∞的边,从所有羊向汇点连一条∞的边,这样就能保证狼和羊都在不同的点集里。然后再从狼到相邻的羊和空地,空地到相邻的空地和羊连一条流量为1的边,最大流求最小割即可。
标签:
原文地址:http://www.cnblogs.com/Bloodline/p/5886241.html