bzoj 1412 狼和羊的故事
题目大意:
将一个矩阵中的1和2分隔,求出最小的分隔代价
思路:
直接连边 所有点向四连块连边 其实也可以
正常的做法是狼到相邻的羊和空地,空地到相邻的空地和羊连一条流量为1的边
最后dinic
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 10101 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,m,a[MAXN/100][MAXN/100]; 21 int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; 22 struct dinic 23 { 24 int fst[MAXN],nxt[MAXN<<4],to[MAXN<<4],val[MAXN<<4],cnt,s,t; 25 void mem() {memset(fst,0xff,sizeof(fst));cnt=-1;} 26 void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;} 27 int vis[MAXN],tot,cur[MAXN],dep[MAXN],q[MAXN]; 28 int bfs() 29 { 30 int l=1,r=0; 31 memset(dep,0xff,sizeof(dep)); 32 vis[t]=++tot,q[++r]=t; 33 while(l<=r) 34 { 35 int x=q[l++]; 36 for(int i=fst[x];i!=-1;i=nxt[i]) 37 if(val[i^1]&&vis[to[i]]!=tot) 38 { 39 //cout<<x<<" "<<to[i]<<endl; 40 vis[to[i]]=tot,dep[to[i]]=dep[x]+1,q[++r]=to[i]; 41 if(to[i]==s) return 1; 42 } 43 } 44 return vis[s]==tot; 45 } 46 int dfs(int x,int a) 47 { 48 if(x==t||!a) return a; 49 int flow=0,f; 50 for(int& i=cur[x];i!=-1;i=nxt[i]) 51 { 52 if(val[i]&&dep[to[i]]==dep[x]-1&&(f=dfs(to[i],min(a,val[i])))) 53 { 54 val[i]-=f,val[i^1]+=f,flow+=f,a-=f; 55 if(!a) break; 56 } 57 } 58 return flow; 59 } 60 int solve() 61 { 62 int ans=0;int f; 63 while(bfs()) 64 { 65 for(int i=0;i<=n*m+1;i++) cur[i]=fst[i]; 66 //cout<<f<<" "<<ans<<endl; 67 while(f=dfs(s,inf)) ans+=f; 68 } 69 return ans; 70 } 71 }D; 72 int main() 73 { 74 n=read(),m=read(),D.s=0,D.t=n*m+1; 75 memset(a,0xff,sizeof(a)); 76 D.mem(); 77 for(int i=1;i<=n;i++) 78 for(int j=1;j<=m;j++) a[i][j]=read(); 79 for(int i=1;i<=n;i++) 80 for(int j=1;j<=m;j++) 81 { 82 if(a[i][j]==1) D.add(0,(i-1)*m+j,inf),D.add((i-1)*m+j,0,0); 83 else if(a[i][j]==2) D.add((i-1)*m+j,D.t,inf),D.add(D.t,(i-1)*m+j,0); 84 for(int k=0;k<4;k++) 85 { 86 int xx=i+dx[k],yy=j+dy[k]; 87 if(xx<1||xx>n||yy<1||yy>m||a[i][j]==2) continue; 88 if(a[i][j]!=1||a[xx][yy]!=1) D.add(i*m-m+j,xx*m-m+yy,1),D.add(xx*m-m+yy,i*m-m+j,0); 89 } 90 } 91 printf("%d",D.solve()); 92 }