hdu 3046 Pleasant sheep and big big wolf 最小割

时间:2023-03-09 03:11:40
hdu 3046 Pleasant sheep and big big wolf 最小割

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3046

In ZJNU, there is a well-known prairie. And it attracts pleasant sheep and his companions to have a holiday. Big big wolf and his families know about this, and quietly hid in the big lawn. As ZJNU ACM/ICPC team, we have an obligation to protect pleasant sheep and his companions to free from being disturbed by big big wolf. We decided to build a number of unit fence whose length is 1. Any wolf and sheep can 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 his Companions to free from being disturbed by big big wolf and his companions.

题目描述:在一个单位方格边长为1的矩阵中藏着灰太狼和它的同伴,等待着喜羊羊和它的同伴,为了不让喜羊羊和同伴被抓住,我们可以在矩形草坪中设置单位长度为1的栅栏,求最短的栅栏长度。

算法分析:最小割模型。新增源点和汇点分别为from和to,源点到喜羊羊和同伴连边,权值为inf,每只狼到汇点连边,权值为inf,然后每个方格到相邻格子连边,权值为1即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int maxn=*+;
int n,m;
struct node
{
int u,flow;
int next;
}edge[maxn*];
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=;
edge[edgenum].next=head[v];
head[v]=edgenum++;
} int d[maxn];
int bfs()
{
memset(d,,sizeof(d));
d[from]=;
queue<int> Q;
Q.push(from);
while (!Q.empty())
{
int u=Q.front() ;Q.pop() ;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].u;
if (!d[v] && edge[i].flow>)
{
d[v]=d[u]+;
Q.push(v);
if (v==to) return ;
}
}
}
return ;
} int dfs(int u,int flow)
{
if (u==to || flow==) return flow;
int cap=flow;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].u;
if (d[v]==d[u]+ && edge[i].flow>)
{
int x=dfs(v,min(cap,edge[i].flow));
cap -= x;
edge[i].flow -= x;
edge[i^].flow += x;
if (cap==) return flow;
}
}
return flow-cap;
}
int dinic()
{
int sum=;
while (bfs()) sum += dfs(from,inf);
return sum;
}
int main()
{
int ncase=;
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-,sizeof(head));
edgenum=;
from=n*m+;
to=from+;
int a;
for (int i= ;i<=n ;i++)
{
for (int j= ;j<=m ;j++)
{
scanf("%d",&a);
if (a==)
{
add(from,(i-)*m+j,inf);
}
else if (a==)
{
add((i-)*m+j,to,inf);
}
if (i->=) add((i-)*m+j,(i-)*m+j,);
if (i+<=n) add((i-)*m+j,i*m+j,);
if (j->=) add((i-)*m+j,(i-)*m+j-,);
if (j+<=m) add((i-)*m+j,(i-)*m+j+,);
}
}
printf("Case %d:\n%d\n",ncase++,dinic());
}
return ;
}