bzoj1412 [ZJOI2009]狼和羊的故事
Description
“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。
Input
文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。
Output
文件中仅包含一个整数ans,代表篱笆的最短长度。
Sample Input
2 2
2 2
1 1
2 2
1 1
Sample Output
2
数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
正解:最小割。
最小割模板题,我也不知道为什么要写这题。。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define inf (1<<30) 6 #define N (10005) 7 8 using namespace std; 9 10 struct edge{ int nt,to,flow,cap; }g[200005]; 11 12 int head[N],d[N],q[N],a[105][105],id[105][105],S,T,n,m,num,cnt; 13 14 il int gi(){ 15 RG int x=0,q=1; RG char ch=getchar(); 16 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 17 if (ch=='-') q=-1,ch=getchar(); 18 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 19 return q*x; 20 } 21 22 il void insert(RG int from,RG int to,RG int cap){ 23 g[++num]=(edge){head[from],to,0,cap},head[from]=num; 24 g[++num]=(edge){head[to],from,0,0},head[to]=num; return; 25 } 26 27 il int bfs(RG int S,RG int T){ 28 memset(d,0,sizeof(d)); 29 RG int h=0,t=1; q[t]=S,d[S]=1; 30 while (h<t){ 31 RG int x=q[++h],v; 32 for (RG int i=head[x];i;i=g[i].nt){ 33 v=g[i].to; 34 if (!d[v] && g[i].cap>g[i].flow){ 35 d[v]=d[x]+1,q[++t]=v; 36 if (v==T) return 1; 37 } 38 } 39 } 40 return d[T]; 41 } 42 43 il int dfs(RG int x,RG int T,RG int a){ 44 if (!a || x==T) return a; RG int f,flow=0; 45 for (RG int i=head[x],v;i;i=g[i].nt){ 46 v=g[i].to; 47 if (d[v]==d[x]+1 && g[i].cap>g[i].flow){ 48 f=dfs(v,T,min(a,g[i].cap-g[i].flow)); 49 if (!f){ d[v]=-1; continue; } 50 g[i].flow+=f,g[i^1].flow-=f; 51 flow+=f,a-=f; if (!a) return flow; 52 } 53 } 54 return flow; 55 } 56 57 il int maxflow(RG int S,RG int T){ 58 RG int flow=0; 59 while (bfs(S,T)) flow+=dfs(S,T,inf); return flow; 60 } 61 62 int main(){ 63 #ifndef ONLINE_JUDGE 64 freopen("story.in","r",stdin); 65 freopen("story.out","w",stdout); 66 #endif 67 n=gi(),m=gi(),num=1,S=++cnt,T=++cnt; 68 for (RG int i=1;i<=n;++i) 69 for (RG int j=1;j<=m;++j) a[i][j]=gi(),id[i][j]=++cnt; 70 for (RG int i=1;i<=n;++i) 71 for (RG int j=1;j<=m;++j){ 72 if (a[i][j]==2) insert(id[i][j],T,inf); else{ 73 if (a[i][j]) insert(S,id[i][j],inf); 74 if (i && a[i-1][j]!=1) insert(id[i][j],id[i-1][j],1); 75 if (j && a[i][j-1]!=1) insert(id[i][j],id[i][j-1],1); 76 if (i<n && a[i+1][j]!=1) insert(id[i][j],id[i+1][j],1); 77 if (j<m && a[i][j+1]!=1) insert(id[i][j],id[i][j+1],1); 78 } 79 } 80 cout<<maxflow(S,T); return 0; 81 }