1. 程式人生 > >BZOJ 1412 狼和羊的故事

BZOJ 1412 狼和羊的故事

memset none 題目 main add sca void close space

首先,題目目的就是為了分割狼群和羊群,即建立超級源和超級匯求最小割從而轉化成用網絡流來處理。

如果沒有空地,那麽就是簡單的二分圖最大匹配,但是題中有空地的出現,所以需要在點與點之間建立雙向邊(不算後向弧),這樣才能滿足題意(我一開始掛到了這裏)

理解透了還是很簡單的

代碼付上

技術分享圖片
  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <queue>
  6 #include <iostream>
  7
using namespace std; 8 #define N 105 9 #define T 10005 10 #define S 0 11 int head[N*N],dep[N*N],cnt,n,m; 12 struct node 13 { 14 int to,next,val; 15 }e[N*N*N]; 16 inline void add(int x,int y,int z) 17 { 18 e[cnt].to=y; 19 e[cnt].val=z; 20 e[cnt].next=head[x]; 21 head[x]=cnt++;
22 return ; 23 } 24 inline void insert(int x,int y,int z) 25 { 26 add(x,y,z); 27 add(y,x,0); 28 return ; 29 } 30 int bfs() 31 { 32 memset(dep,-1,sizeof(dep)); 33 queue <int >q; 34 q.push(S); 35 dep[S]=1; 36 while(!q.empty()) 37 { 38 int
x=q.front();q.pop(); 39 for(int i=head[x];i!=-1;i=e[i].next) 40 { 41 int to1=e[i].to; 42 if(dep[to1]==-1&&e[i].val) 43 { 44 q.push(to1); 45 dep[to1]=dep[x]+1; 46 } 47 } 48 } 49 return dep[T]==-1?0:1; 50 } 51 int dfs(int x,int maxf) 52 { 53 if(!maxf)return 0; 54 if(x==T)return maxf; 55 int tflow=maxf,nowf; 56 for(int i=head[x];i!=-1;i=e[i].next) 57 { 58 int to1=e[i].to; 59 if(dep[to1]==dep[x]+1&&e[i].val&&dep[x]!=-1) 60 { 61 nowf=dfs(to1,min(e[i].val,tflow)); 62 if(!nowf) 63 { 64 dep[to1]=-1; 65 continue; 66 } 67 tflow-=nowf; 68 e[i].val-=nowf,e[i^1].val+=nowf; 69 if(!tflow)break; 70 } 71 } 72 dep[x]=-1; 73 return maxf-tflow; 74 } 75 int map[N][N]; 76 int dx[4]={0,1,0,-1}; 77 int dy[4]={1,0,-1,0}; 78 int main() 79 { 80 memset(head,-1,sizeof(head)); 81 scanf("%d%d",&n,&m); 82 for(int i=1;i<=n;i++) 83 { 84 for(int j=1;j<=m;j++) 85 { 86 int x; 87 scanf("%d",&x); 88 map[i][j]=x; 89 if(x==2)insert((i-1)*m+j,T,1<<30); 90 if(x==1)insert(S,(i-1)*m+j,1<<30); 91 } 92 } 93 for(int i=1;i<=n;i++) 94 { 95 for(int j=1;j<=m;j++) 96 { 97 for(int k=0;k<4;k++) 98 { 99 int ty=dx[k]+i,tx=dy[k]+j; 100 if(ty==0||ty==n+1)continue; 101 if(tx==0||tx==m+1)continue; 102 int f=(i-1)*m+j,t=(ty-1)*m+tx; 103 insert(f,t,1); 104 } 105 } 106 } 107 int ans=0; 108 while(bfs()) 109 { 110 ans+=dfs(S,1<<30); 111 } 112 printf("%d\n",ans); 113 return 0; 114 }
View Code

BZOJ 1412 狼和羊的故事