HDU 3046-Pleasant sheep and big big wolf(网络流_最小割)

Pleasant sheep and big big wolf

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2254    Accepted Submission(s): 946

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

题意:在一个n*m的草原上,羊是1,狼是2,要安长度为1的栅栏,要求用最小的栅栏保证羊不被狼吃掉。

思路:建立一个超级源点与狼相连,长度为inf,建立一个超级汇点与羊相连,长度为inf,然后剩下的格子相连长度为1,然后找。

这个图真心怪怪的,一开始用搜索找四个方向,愣是不对,最后只好用笨办法,一个一个来喽。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <queue>
#include <map>

using namespace std;
const int inf=0x3f3f3f3f;
int head[1000100],num[100010],d[100010],pre[100010],cur[100010],mp[310][310];
int n,m,cnt,nv,s,t;
int jx[]={1,0,-1,0};
int jy[]={0,1,0,-1};
struct node
{
    int u,v,cap;
    int next;
}edge[10000010];

void add(int u, int v, int cap)
{
    edge[cnt].v=v;
    edge[cnt].cap=cap;
    edge[cnt].next=head[u];
    head[u]=cnt++;

    edge[cnt].v=u;
    edge[cnt].cap=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}

void bfs()
{
    memset(d,-1,sizeof(d));
    memset(num,0,sizeof(num));
    queue<int >q;
    q.push(t);
    d[t]=0;
    num[0]=1;
    while(!q.empty()) {
        int i;
        int u=q.front();
        q.pop();
        for(i=head[u]; i!=-1; i=edge[i].next) {
            int v=edge[i].v;
            if(d[v]==-1) continue;
            d[v]=d[u]+1;
            num[d[v]]++;
            q.push(v);
        }
    }
}

void isap()
{
    memcpy(cur,head,sizeof(cur));
    int flow=0, u=pre[s]=s, i;
    bfs();
    while(d[s]<nv) {
        if(u==t) {
            int f=inf, pos;
            for(i=s; i!=t; i=edge[cur[i]].v) {
                if(f>edge[cur[i]].cap) {
                    f=edge[cur[i]].cap;
                    pos=i;
                }
            }
            for(i=s; i!=t; i=edge[cur[i]].v) {
                edge[cur[i]].cap-=f;
                edge[cur[i]^1].cap+=f;
            }
            flow+=f;
            u=pos;
        }
        for(i=cur[u]; i!=-1; i=edge[i].next) {
            if(d[edge[i].v]+1==d[u]&&edge[i].cap)
                break;
        }
        if(i!=-1) {
            cur[u]=i;
            pre[edge[i].v]=u;
            u=edge[i].v;
        } else {
            if(--num[d[u]]==0) break;
            int mind=nv;
            for(i=head[u]; i!=-1; i=edge[i].next) {
                if(mind>d[edge[i].v]&&edge[i].cap) {
                    mind=d[edge[i].v];
                    cur[u]=i;
                }
            }
            d[u]=mind+1;
            num[d[u]]++;
            u=pre[u];
        }
    }
    printf("%d\n",flow);
}

int main()
{
    int i, j,k;
    int tt=1;
    while(~scanf("%d%d",&n,&m))
    {
        cnt=0;
        s=0;
        t=n*m+1;
        nv=t+1;
        memset(head,-1,sizeof(head));
        for(i=1; i<=n; i++)
        {
            for(j=1; j<=m; j++)
            {
                scanf("%d",&mp[i][j]);
                if(mp[i][j]==1)
                    add(s,(i-1)*m+j,inf);
                if(mp[i][j]==2)
                    add((i-1)*m+j,t,inf);
                if(i!=1)
                    add((i-1)*m+j,(i-2)*m+j,1);// 与上面的点相连
                if(i!=n)
                    add((i-1)*m+j,i*m+j,1);//与下面的点相连
                if(j!=1)
                    add((i-1)*m+j,(i-1)*m+j-1,1);//与左边的点相连
                if(j!=m)
                    add((i-1)*m+j,(i-1)*m+j+1,1);//与右边的点相连
                }
            }
        printf("Case %d:\n",tt++);
        isap();
    }
    return 0;
}
时间: 2024-10-21 05:04:14

HDU 3046-Pleasant sheep and big big wolf(网络流_最小割)的相关文章

HDU 3046 Pleasant sheep and big big wolf(最小割)

HDU 3046 Pleasant sheep and big big wolf 题目链接 题意:一个n * m平面上,1是羊,2是狼,问最少要多少围墙才能把狼全部围住,每有到达羊的路径 思路:有羊和狼,要分成两个集合互不可达,显然的最小割,建图源点连狼,容量无穷,羊连汇点,容量无穷,然后相邻格子连边,容量为1 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm

HDU 3046 Pleasant sheep and big big wolf

Pleasant sheep and big big wolf Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 304664-bit integer IO format: %I64d      Java class name: Main In ZJNU, there is a well-known prairie. And it attracts pleasant

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 A

hdoj 3046 Pleasant sheep and big big wolf 【最小割】

Pleasant sheep and big big wolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2570    Accepted Submission(s): 1056 Problem Description In ZJNU, there is a well-known prairie. And it attracts

【HDU 5855】Less Time, More profit(网络流、最小割、最大权闭合子图)

Less Time, More profit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description The city planners plan to build N plants in the city which has M shops. Each shop needs products from some plants to make p

HDU 4859-海岸线(网络流_最小割)

海岸线 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 161    Accepted Submission(s): 90 Problem Description 欢迎来到珠海! 由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的决策人,在仔细观察了Z市地图之后,你准备通过填充某些海域来扩展Z市的海岸线

Pleasant sheep and big big wolf (hdu 3046 最小割)

Pleasant sheep and big big wolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2371    Accepted Submission(s): 988 Problem Description In ZJNU, there is a well-known prairie. And it attracts p

HDU 3046Pleasant sheep and big big wolf(网络流之最小割)

题目地址:HDU 3046 最小割第一发!其实也没什么发不发的...最小割==最大流.. 入门题,但是第一次入手最小割连入门题都完全没思路...sad..对最小割的本质还是了解的不太清楚.. 这题就是对每两个相邻的格子的边界都要进行加边,然后求最大流就OK了. RE了好长时间,注意遍历加边的时候要从1开始,而不是0开始,因为0是源点的...(也许只有我才犯这种错误吧...)建图不多说了..只要了解了最小割,建图还是很容易想的. 代码如下: #include <iostream> #includ

Pleasant sheep and big big wolf

点击打开链接 题目:在一个N * M 的矩阵草原上,分布着羊和狼,每个格子只能存在0或1只动物.现在要用栅栏将所有的狼和羊分开,问怎么放,栅栏数放的最少,求出个数? 解析:将狼群看作一个集合,羊群看作一个集合.然后设置源点和汇点,将两点至存在动物的点的距离赋值为1,构图,由于求得是栅栏数,从存在动物的位置向四周发散点赋值为1,即该方向放置一个栅栏.然后可以发现变成了求最小割,即求出最大流.需要注意的是,由于数据比较大,200 * 200.如果设置源点和汇点相差较大(即s = 0,e = n *