HDU3046 Pleasant sheep and big big wolf
Problem Description
In ZJNU, there isa well-known prairie. And it attracts pleasant sheep and his companions to havea holiday. Big big wolf and his families know about this, and quietly hid inthe big lawn. As ZJNU ACM/ICPC team, we have an obligation to protect pleasantsheep and his companions to free from being disturbed by big big wolf. Wedecided to build a number of unit fence whose length is 1. Any wolf and sheepcan not cross the fence. Of course, one grid can only contain an animal.
Now, we ask to place the minimum fences to let pleasant sheep and hisCompanions to free from being disturbed by big big wolf and hiscompanions.
Input
There are manycases.
For every case:
N and M(N,M<=200)
then N*M matrix:
0 is empty, and 1 is pleasant sheep and his companions, 2 is big big wolf andhis companions.
Output
For every case:
First line output “Case p:”, p is the p-th case;
The second line is the answer.
Sample Input
4 6
1 0 0 1 0 0
0 1 1 0 0 0
2 0 0 0 0 0
0 2 0 1 1 0
Sample Output
Case 1:
4
题目大意:
地图中:
0——空地
1——羊
2——狼
在数字间隙间建围栏,阻止狼吃羊
最大流=最小割
对了,有多次测试Case
输入:
行 列
* * * * * *
* * * * * *
* * * * * *
* * * * * *(map)
输出:
Case 1(2,3,......)
最小割
思路:
将矩阵动物上建立c=1网络,建立超级源点s连接所有的羊,超级汇点t连接所有的狼,最大流=最小割
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int maxn=200*200+10;
int n,m;
struct node
{
int u,flow;
int next;
}edge[maxn*4];
int head[maxn],edgenum;
int from,to;
void add(int u,int v,int flow)
{
edge[edgenum].u=v ;edge[edgenum].flow=flow;
edge[edgenum].next=head[u];
head[u]=edgenum++;
edge[edgenum].u=u ;edge[edgenum].flow=0;
edge[edgenum].next=head[v];
head[v]=edgenum++;
}
int d[maxn];
int bfs()
{
memset(d,0,sizeof(d));
d[from]=1;
queue<int> Q;
Q.push(from);
while (!Q.empty())
{
int u=Q.front() ;Q.pop() ;
for (int i=head[u] ;i!=-1 ;i=edge[i].next)
{
int v=edge[i].u;
if (!d[v] && edge[i].flow>0)
{
d[v]=d[u]+1;
Q.push(v);
if (v==to) return 1;
}
}
}
return 0;
}
int dfs(int u,int flow)
{
if (u==to || flow==0) return flow;
int cap=flow;
for (int i=head[u] ;i!=-1 ;i=edge[i].next)
{
int v=edge[i].u;
if (d[v]==d[u]+1 && edge[i].flow>0)
{
int x=dfs(v,min(cap,edge[i].flow));
cap -= x;
edge[i].flow -= x;
edge[i^1].flow += x;
if (cap==0) return flow;
}
}
return flow-cap;
}
int dinic()
{
int sum=0;
while (bfs()) sum += dfs(from,inf);
return sum;
}
int main()
{
freopen("喜羊羊和灰太狼.txt","r",stdin);
int js=1;
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-1,sizeof(head));
edgenum=0;
from=n*m+1;
to=from+1;
int a;
for (int i=1 ;i<=n ;i++)
{
for (int j=1 ;j<=m ;j++)
{
scanf("%d",&a);
if (a==1)
{
add(from,(i-1)*m+j,inf);
}
else if (a==2)
{
add((i-1)*m+j,to,inf);
}
if (i-1>=1) add((i-1)*m+j,(i-2)*m+j,1);
if (i+1<=n) add((i-1)*m+j,i*m+j,1);
if (j-1>=1) add((i-1)*m+j,(i-1)*m+j-1,1);
if (j+1<=m) add((i-1)*m+j,(i-1)*m+j+1,1);
}
}
printf("Case %d:\n%d\n",js++,dinic());
}
return 0;
}