【BZOJ】【1412】【ZJOI2009】狼和羊的故事
网络流/最小割
一开始我是将羊的区域看作连通块,狼的区域看作另一种连通块,S向每个羊连通块连一条无穷边,每个狼连通块向T连一条无穷边,连通块内部互相都是无穷边。其余是四连通的流量为1的边……然后WA了= =自己的数据和样例都过了……
然后orz了一下Hzwer,改成对每个羊/狼都单独连一条无穷边,分界线/0点周围 连容量1的边……AC……
1 /************************************************************** 2 Problem: 1412 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:232 ms 7 Memory:3224 kb 8 ****************************************************************/ 9 10 //BZOJ 1412 11 #include<vector> 12 #include<cstdio> 13 #include<cstring> 14 #include<cstdlib> 15 #include<iostream> 16 #include<algorithm> 17 #define rep(i,n) for(int i=0;i<n;++i) 18 #define F(i,j,n) for(int i=j;i<=n;++i) 19 #define D(i,j,n) for(int i=j;i>=n;--i) 20 #define pb push_back 21 using namespace std; 22 inline int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 25 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 26 return v*sign; 27 } 28 const int N=21010,M=100000,INF=~0u>>2; 29 const int fx[]={0,1,0,-1}, 30 fy[]={1,0,-1,0}; 31 typedef long long LL; 32 /******************tamplate*********************/ 33 int n,m,a[110][110]; 34 struct edge{ 35 int from,to,v; 36 }; 37 inline int pack(int i,int j){ return (i-1)*m+j; } 38 struct Net{ 39 edge E[M]; 40 int head[N],next[M],cnt; 41 bool vis[110][110]; 42 void add(int x,int y,int v){ 43 E[++cnt]=(edge){x,y,v}; 44 next[cnt]=head[x]; head[x]=cnt; 45 E[++cnt]=(edge){y,x,0}; 46 next[cnt]=head[y]; head[y]=cnt; 47 } 48 int s,t,cur[N],d[N],Q[N]; 49 void bfs(int x,int y){ 50 rep(k,4){ 51 int tx=x+fx[k],ty=y+fy[k]; 52 if (a[tx][ty]==a[x][y] &&!a[x][y]) 53 add(pack(x,y),pack(tx,ty),1); 54 if (a[tx][ty]!=a[x][y]&&a[tx][ty]!=-1) 55 add(pack(x,y),pack(tx,ty),1); 56 } 57 } 58 void init(){ 59 n=getint();m=getint(); 60 cnt=1; 61 s=0;t=n*m+1; 62 int x,y; 63 memset(a,-1,sizeof a); 64 memset(vis,0,sizeof vis); 65 F(i,1,n) F(j,1,m) a[i][j]=getint(); 66 F(i,1,n) F(j,1,m){ 67 bfs(i,j); 68 if (a[i][j]==1) add(s,pack(i,j),INF); 69 if (a[i][j]==2) add(pack(i,j),t,INF); 70 } 71 } 72 bool mklevel(){ 73 memset(d,-1,sizeof d); 74 d[s]=0; 75 int l=0,r=-1; 76 Q[++r]=s; 77 while(l<=r){ 78 int x=Q[l++]; 79 for(int i=head[x];i;i=next[i]) 80 if (d[E[i].to]==-1 && E[i].v){ 81 d[E[i].to]=d[x]+1; 82 Q[++r]=E[i].to; 83 } 84 } 85 return d[t]!=-1; 86 } 87 int dfs(int x,int a){ 88 if (x==t||a==0) return a; 89 int flow=0; 90 for(int &i=cur[x];i && flow<a;i=next[i]) 91 if (d[E[i].to]==d[x]+1 && E[i].v){ 92 int f=dfs(E[i].to,min(a-flow,E[i].v)); 93 E[i].v-=f; 94 E[i^1].v+=f; 95 flow+=f; 96 } 97 if (!flow) d[x]=-1; 98 return flow; 99 } 100 int Dinic(){ 101 int flow=0; 102 while(mklevel()){ 103 F(i,s,t) cur[i]=head[i]; 104 flow+=dfs(s,INF); 105 } 106 return flow; 107 } 108 }G1; 109 int main(){ 110 #ifndef ONLINE_JUDGE 111 freopen("1412.in","r",stdin); 112 freopen("1412.out","w",stdout); 113 #endif 114 G1.init(); 115 printf("%d\n",G1.Dinic()); 116 return 0; 117 }