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

Sample Output

2
数据范围
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 }

 

posted @ 2018-02-27 08:49  wfj_2048  阅读(186)  评论(0编辑  收藏  举报