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

来源:互联网 发布:手机淘宝在哪看退货率 编辑:程序博客网 时间:2024/05/22 16:54

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 MN,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 0x3f3f3f3fstruct 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();    }}



0 0