hdu 3046(最小割最大流)

原创 2016年05月31日 09:39:47

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

解题思路:这道题是要把狼和羊分开,如果熟悉最小割的话,就比较容易了,将所有的羊同源点连一条无穷大的边,狼和汇点连一条无穷大的边,剩下的格子与周围格子连一条容量为1的边,接下来就是求最小割即可。主要是为什么这样建图就是对的,首先是容量为1的边,这个比较好理解,两个相邻格子只要加一个栅栏就可以隔开了。接下来是无穷大的边,因为羊的限制是由它周围的格子决定的,与源点无关,而且回顾最小割,羊与源点的边集肯定不会在最小割集里,这样也符合实际问题。

#include <cstring>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#define INF 0x3fffffff
#define MAXN 205
using namespace std;

int N, M, G[MAXN][MAXN], dis[MAXN*MAXN];
int dir[2][2] = {0, 1, 1, 0};
int idx, head[MAXN*MAXN];
const int sink = MAXN*MAXN-1, source = MAXN*MAXN-2;

struct Edge
{
    int v, cap, next;
}e[MAXN*MAXN*4];

inline void init()
{ 
    idx = -1;
    memset(head, 0xff, sizeof (head));
}

inline int to(int x, int y)
{
    return (x-1)*M+(y-1);
}

inline void insert(int a, int b, int c)
{
    ++idx;
    e[idx].v = b, e[idx].cap = c;
    e[idx].next = head[a], head[a] = idx;
}

inline bool judge(int x, int y)
{
    if (x < 1 || x > N || y < 1 || y > M) {
        return false;
    }
    return true;
}

inline void check(int x, int y)
{
    int xx, yy;
    if (G[x][y] == 1) {
        insert(to(x, y), sink, INF);
        insert(sink, to(x, y), 0); 
    }
    else if (G[x][y] == 2) {
        insert(source, to(x, y), INF);
        insert(to(x, y), source, 0); 
    }  
    for (int i = 0; i < 2; ++i) {
        xx = x + dir[i][0], yy = y + dir[i][1];
        if (judge(xx, yy)) {
            insert(to(x, y), to(xx, yy), 1);
            insert(to(xx, yy), to(x, y), 1);
        }
    }
}

bool bfs()
{
    int pos;
    queue<int>q;
    memset(dis, 0xff, sizeof (dis));
    dis[source] = 0;
    q.push(source);
    while (!q.empty()) {
        pos = q.front();
        q.pop();
        for (int i = head[pos]; i != -1; i = e[i].next) {
            if (dis[e[i].v] == -1 && e[i].cap > 0) {
                dis[e[i].v] = dis[pos]+1;
                q.push(e[i].v);
            }
        }
    }
    return dis[sink] != -1;
}

int dfs(int u, int flow)
{
    if (u == sink) {
        return flow;
    }
    int tf = 0, sf;
    for (int i = head[u]; i != -1; i = e[i].next) {
        if (dis[u]+1 == dis[e[i].v] && e[i].cap > 0 && (sf = dfs(e[i].v, min(flow-tf, e[i].cap)))) {
            e[i].cap -= sf, e[i^1].cap += sf;
            tf += sf;
            if (tf == flow) {
                return flow;
            }
        }
    }
    if (!tf) {
        dis[u] = -1;
    }
    return tf;
}

int dinic()
{
    int ans = 0;
    while (bfs()) {
        ans += dfs(source, INF);
    }
    return ans;
}

int main()
{   
    int ca = 0;
    while (scanf("%d %d", &N, &M) == 2) {
        init();
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= M; ++j) {
                scanf("%d", &G[i][j]);
            }
        }
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= M; ++j) {
                check(i, j);
            }
        }
        printf("Case %d:\n%d\n", ++ca, dinic());
    }
    return 0;
}


HDU 3046 最大流最小割

传送门 思路: 把每个格子想成点,相邻格子之间有条无向边(容量1),源点连接狼,容量INF,汇点连接羊,容量INF,构图,求最小割的和,就是最大流。 注意怎么表示边!!!#include #in...
  • naipp
  • naipp
  • 2016年07月21日 21:07
  • 76

HDU 3046 最大流最小割问题

Pleasant sheep and big big wolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768...
  • NLSQQ
  • NLSQQ
  • 2016年07月12日 20:06
  • 84

【网络流】HDU3046 Pleasant sheep and big big wolf (最小割/最大流)

Pleasant sheep and big big wolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 ...
  • Gengman
  • Gengman
  • 2017年02月24日 20:11
  • 226

网络最大流-最小割问题

  • 2010年11月03日 20:22
  • 240KB
  • 下载

最大流与最小割

  • 2014年03月13日 13:30
  • 20KB
  • 下载

HDU 4289 最大流最小割

点击打开链接 题意:给定的点中,每个点都有自己的权值,问从s走到d,删除几个点之后走不到了,且这几个点的权值最小 思路:看着就像是最小割,直接模版敲完,因为权值在点上,而不是边上,所以要将点拆开,...
  • Dan__ge
  • Dan__ge
  • 2016年04月05日 15:49
  • 727

最大流最小割

  • 2017年08月24日 23:54
  • 198KB
  • 下载

最大流最小割定理.pptx

  • 2016年10月02日 18:25
  • 161KB
  • 下载

HDU-4859-海岸线(最大流最小割)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4859 #include #define MAXN 30007 #define MAXM...

HDU 4289 Control(最大流、最小割)

Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 3046(最小割最大流)
举报原因:
原因补充:

(最多只允许输入30个字)