zoukankan      html  css  js  c++  java
  • hdu 2732 Leapin' Lizards 最大流 拆点 建图

    题目链接

    题意

    给定一张网格,格子中有些地方有柱子,有些柱子上面有蜥蜴。

    每个柱子只能承受有限只蜥蜴从上面经过。每只蜥蜴每次能走到相距曼哈顿距离(leq k)的格子中去。

    问有多少只蜥蜴能走出网格。

    分析

    参考博文

    拆点

    因为这道题中的容量不是限制在边上,而是限制在点上的,所以可以考虑将一个点拆成两个点,中间再加一条边,边的容量即为原先点上的值。

    想法很重要。

    建图

    1. 对于起始有蜥蜴的点,从源点(s)连一条容量为(1)的边到它;

    2. 对于中间点,拆成两点:点(1)到点(2)的容量为点的承受值;点(2)再代表原先的该点向外连向其他点,权值可以赋为大于等于容量的任意值;

    3. 对于可以直接跳出去的点,向汇点(e)连一条边,容量为该点的承受值。

    跑最大流

    Code

    #include <bits/stdc++.h>
    #define maxn 1010
    #define maxp 1010
    #define inf 0x3f3f3f3f
    #define id1(i,j) (idx(i,j)<<1)
    #define id2(i,j) (id1(i,j)|1)
    using namespace std;
    typedef long long LL;
    int dep[maxp], cur[maxp], n, m, tot, k, ne[maxp];
    char cnt[maxn][maxn], s[maxn];
    inline int idx(int i, int j) { return (i-1)*m+j; }
    inline bool check(int i, int j) { return i > 0 && i <= n && j > 0 && j <= m && cnt[i][j]!='0'; }
    struct Edge { int to, ne, c; }edge[maxp<<4];
    void add(int u, int v, int c) {
        edge[tot] = {v, ne[u], c};
        ne[u] = tot++;
        edge[tot] = {u, ne[v], 0};
        ne[v] = tot++;
    }
    void init() {
        tot = 0; memset(ne, -1, sizeof(ne));
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                if (cnt[i][j] == '0') continue;
                if (i-k <= 0 || i+k > n || j-k <= 0 || j+k > m) { add(id1(i,j), 1, cnt[i][j]-'0'); continue; }
                add(id1(i,j), id2(i,j), cnt[i][j]-'0');
                for (int r = i-k; r <= i+k; ++r) {
                    for (int c = j-k; c <= j+k; ++c) {
                        if (abs(i-r)+abs(j-c) > k) continue;
                        if (check(r, c)) add(id2(i, j), id1(r, c), inf);
                    }
                }
            }
        }
    }
    int bfs(int src) {
        queue<int> q;
        while (!q.empty()) q.pop();
        memset(dep, 0, sizeof(dep));
        dep[src] = 1;
        q.push(src);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int i = ne[u]; ~i; i = edge[i].ne) {
                int v = edge[i].to;
                if (edge[i].c > 0 && !dep[v]) {
                    dep[v] = dep[u]+1;
                    q.push(v);
                }
            }
        }
        return dep[1];
    }
    int dfs(int u, int flow) {
        if (u == 1) return flow;
        for (int& i = cur[u]; ~i; i = edge[i].ne) {
            int v = edge[i].to;
            if (edge[i].c > 0 && dep[v]-dep[u]==1) {
                int c = dfs(v, min(flow, edge[i].c));
                if (c) {
                    edge[i].c -= c;
                    edge[i^1].c += c;
                    return c;
                }
            }
        }
        return 0;
    }
    int kas;
    void work() {
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; ++i) {
            scanf("%s", cnt[i]+1);
        }
        m = strlen(cnt[1]+1);
        init();
    
        int all = 0;
        for (int i = 1; i <= n; ++i) {
            scanf("%s", s+1);
            for (int j = 1; j <= m; ++j) {
                if (s[j] == 'L') ++all, add(0, id1(i,j), 1);
            }
        }
    
        int pcnt = id2(n, m)+1, ans=0, ret;
        while (bfs(0)) {
            for (int i = 0; i < pcnt; ++i) cur[i] = ne[i];
            while (ret = dfs(0, inf)) ans += ret;
        }
        ans = all-ans;
        printf("Case #%d: ", ++kas);
        if (!ans) puts("no lizard was left behind.");
        else if (ans==1) puts("1 lizard was left behind.");
        else printf("%d lizards were left behind.
    ", ans);
    }
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) work();
        return 0;
    }
    
    
  • 相关阅读:
    创建基于MailKit和MimeKit的.NET基础邮件服务
    MailKit---获取邮件
    C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
    .net 开源 FTP 组件 edtFTPnet
    Consul1-window安装consul
    通信传输利器Netty(Net is DotNetty)介绍
    工作中,如何衡量一个人的 JavaScript 编码水平?
    10个有趣又能编译为JavaScript的语言,你用过哪些?
    一定要你明白Java中的volatile
    面试总被问到HTTP缓存机制及原理?看完你就彻底明白了
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7725503.html
Copyright © 2011-2022 走看看