您的位置:首页 > 其它

hdu 3046 Pleasant sheep and big big wolf【最大流Dinic--------最小割】

2016-08-20 14:35 399 查看

Pleasant sheep and big big wolf

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2858    Accepted Submission(s): 1180


Problem Description

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. 

Input

There are many cases. 

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 and his 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

Source

2009 Multi-University Training Contest 14 - Host by
ZJNU

 

题目大意:

在一个n*m的矩阵上,1代表羊,2代表狼,0代表平地,我们有长度为1的一个栅栏(不是放在格子上的,是放在格子和格子之间的空隙上的),问使用最少的栅栏,能够使得狼吃不到羊。

思路:

1、建立最小割模型:

①建立源点S,将源点S连入各个有狼的节点上,权值设定为INF,表示狼可以从任意方向出发。

②建立汇点T,将各个羊节点连入汇点T,权值设定为INF。

③将每两个相邻的格子之间建立一条边,权值设定为1,表示如果拆掉了这条边,这条边就不能走了。

2、那么建立好这个网络之后,跑一遍最大流Dinic,其值最大流==最小割,其实就是相当于求得最少需要割除多少边能够使得从源点S不能到汇点T,那么其解,就是maxflow、

Ac代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
struct node
{
int from;
int to;
int next;
int w;
}e[1515151];
int a[500][500];
int head[500*500];
int cur[500*500];
int divv[500*500];
int fx[4]={0,0,1,-1};
int fy[4]={1,-1,0,0};
int n,m,ss,tt,cont;
void add(int from,int to,int w)
{
e[cont].to=to;
e[cont].w=w;
e[cont].next=head[from];
head[from]=cont++;
}
int makedivv()
{
queue<int >s;
memset(divv,0,sizeof(divv));
divv[ss]=1;
s.push(ss);
while(!s.empty())
{
int u=s.front();
s.pop();
if(u==tt)return 1;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(w&&divv[v]==0)
{
divv[v]=divv[u]+1;
s.push(v);
}
}
}
return 0;
}
int Dfs(int u,int maxflow,int tt)
{
if(u==tt)return maxflow;
int ret=0;
for(int &i=cur[u];i!=-1;i=e[i].next)
{
int w=e[i].w;
int v=e[i].to;
if(divv[v]==divv[u]+1)
{
int f=Dfs(v,min(maxflow-ret,w),tt);
e[i].w-=f;
e[i^1].w+=f;
ret+=f;
if(ret==maxflow)return ret;
}
}
return ret;
}
void Dinic()
{
int ans=0;
while(makedivv()==1)
{
memcpy(cur,head,sizeof(head));
ans+=Dfs(ss,INF,tt);
}
printf("%d\n",ans);
}
int main()
{
int kase=0;
while(~scanf("%d%d",&n,&m))
{
ss=n*m+1;
tt=ss+1;
cont=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==2)
{
add(ss,(i-1)*m+j,INF);
add((i-1)*m+j,ss,0);
}
if(a[i][j]==1)
{
add((i-1)*m+j,tt,INF);
add(tt,(i-1)*m+j,0);
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<4;k++)
{
int xx=i+fx[k];
int yy=j+fy[k];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m)
{
add((i-1)*m+j,(xx-1)*m+yy,1);
add((xx-1)*m+yy,(i-1)*m+j,0);
}
}
}
}
printf("Case %d:\n",++kase);
Dinic();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 3046 杭电 3046