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
最小割……好久不做网络流这么简单的建模都不会了……把狼和周围的空地和羊连边,空地和周围的空地和羊连边S连狼,INF E连羊,INF
1 #include2 #include 3 #include 4 #include 5 #include 6 #define MAXM (1000000+10) 7 #define MAXN (30000+10) 8 #define id(x,y) (x-1)*m+y 9 using namespace std;10 struct node11 {12 int Flow;13 int next;14 int to;15 } edge[MAXM*2];16 int Depth[MAXN];17 int head[MAXN],num_edge;18 int n,m,s,e,x,y,INF,a[105][105];19 int dx[5]= { 0,1,-1,0,0},dy[5]= { 0,0,0,1,-1};20 queue q;21 22 void add(int u,int v,int l)23 {24 edge[++num_edge].to=v;25 edge[num_edge].Flow=l;26 edge[num_edge].next=head[u];27 head[u]=num_edge;28 }29 30 bool Bfs(int s,int e)31 {32 memset(Depth,0,sizeof(Depth));33 q.push(s);34 Depth[s]=1;35 while (!q.empty())36 {37 int x=q.front();38 q.pop();39 for (int i=head[x]; i!=0; i=edge[i].next)40 if (!Depth[edge[i].to] && edge[i].Flow>0)41 {42 Depth[edge[i].to]=Depth[x]+1;43 q.push(edge[i].to);44 }45 }46 return Depth[e];47 }48 49 int Dfs(int x,int low)50 {51 int Min,f=0;52 if (x==e || low==0)53 return low;54 for (int i=head[x]; i!=0; i=edge[i].next)55 if (edge[i].Flow>0 && Depth[edge[i].to]==Depth[x]+1 && (Min=Dfs(edge[i].to,min(low,edge[i].Flow))))56 {57 edge[i].Flow-=Min;58 edge[((i-1)^1)+1].Flow+=Min;59 low-=Min;60 f+=Min;61 if (low==0) return f;62 }63 if (!f) Depth[x]=-1;64 return f;65 }66 67 int Dinic(int s,int e)68 {69 int Ans=0;70 while (Bfs(s,e))71 Ans+=Dfs(s,0x7fffffff);72 return Ans;73 }74 75 int main()76 {77 memset(&INF,0x7f,sizeof(INF));78 s=0,e=10001;79 scanf("%d%d",&n,&m);80 for (int i=1; i<=n; ++i)81 for (int j=1; j<=m; ++j)82 {83 scanf("%d",&a[i][j]);84 if (a[i][j]==2) add(s,id(i,j),INF),add(id(i,j),s,0);85 if (a[i][j]==1) add(id(i,j),e,INF),add(e,id(i,j),0);86 for (int k=1; k<=4; ++k)87 {88 int x=i+dx[k],y=j+dy[k];89 if (x<1 || x>n || y<1 || y>m) continue;90 if (a[i][j]==2 && a[x][y]!=2 || a[i][j]==0 && a[i][j]!=2)91 add(id(i,j),id(x,y),1),add(id(x,y),id(i,j),0);92 }93 }94 printf("%d\n",Dinic(s,e));95 }