• BZOJ1001 洛谷4001 [BJOI2006]狼抓兔子 题解


    题目

    这个题目有多种解法,这个题也是一个比较经典的题了,正是因为他的多样的做法,这个题主要难在建图和优化,因为这是一个网格图,所以spfa肯定过不去,所以用最短路解法的话,只能用dij,而网络流也是要加上几个必不可少的优化,具体在代码中解释:

    代码:

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    #define M 6000100
    #define N 200100
    #define inf 1 << 30
    using namespace std;
    queue <int> q;
    struct cym {
        int to, next, len;
    }e[M * 2];
    int lin[M * 2], cnt = 1;
    int n, m, s, t, deep[M];
    inline void add(int u, int v, int w)
    {
        e[++cnt].to = v;
        e[cnt].len = w;
        e[cnt].next = lin[u];
        lin[u] = cnt;
    }
    inline bool bfs()
    {
        int i, now;
        memset(deep, 0 ,sizeof(deep));
        q.push(s);
        deep[s] = 1;
        while(!q.empty())
        {
            int now = q.front();
            q.pop();
            for(int i = lin[now]; i; i = e[i].next)
            {
                if(e[i].len && !deep[e[i].to])
                {
                    deep[e[i].to] = deep[now] + 1;
                    q.push(e[i].to);
                }
            }
        }
        if(deep[t] > 0)
            return 1;    
        return 0;
    }
    int dfs(int x, int maxflow)//maxflow是当前最多可以流多少流量
    {
        if(x == t || maxflow == 0)
            return maxflow;
        int w, used = 0;
        for(int i = lin[x]; i; i = e[i].next)
        {
            if(deep[e[i].to] == deep[x] + 1 && e[i].len)
            {
                w = dfs(e[i].to, min(maxflow - used, e[i].len));//w=这条边权的最小值或当前最多可以流的流量减去当前增广的流量
                if(!w)//如果当前不能走了,就把这条路封掉,封掉的方法就是把层数设为0
                {
                    deep[e[i].to] = 0;
                    continue;
                }
                used += w;//当前可以流的流量
                e[i].len -= w;
                e[i ^ 1].len += w;
                if(used == maxflow)//相当于当前用光了 ,没有可以增广的流量了
                    return used; 
            }
        }
        if(!used)//used 是现在可以增广的流量        
            deep[x] = 0;
        return used;
    }
    int dinic()
    {
        int ans = 0;
        while(bfs())
        {
            ans += dfs(s, inf);
        }
        return ans;
    }
    inline int read() {
        char ch = getchar(); int x = 0, f = 1;
        while(ch < '0' || ch > '9') {
            if(ch == '-') f = -1;
            ch = getchar();
        } while('0' <= ch && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        } return x * f;
    }
    int main()
    {
        n = read(), m = read();
        s = 1, t = n * m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j < m; j++)
            {
                int w;
                w = read();
                add ( (i - 1) * m + j, (i - 1) * m + j + 1, w);
                add ( (i - 1) * m + j + 1, (i - 1) * m + j, w);
            }
        for (int i = 1; i < n; i++)
            for (int j = 1; j <= m; j++)
            {
                int w;
                w = read();
                add ( (i - 1) * m + j, (i - 1) * m + j + m, w);
                add ( (i - 1) * m + j + m, (i - 1) * m + j, w);
            }
        for (int i = 1; i < n; i++)
            for (int j = 1; j < m; j++)
            {
                int w;
                w = read();
                add ( (i - 1) * m + j, (i - 1) * m + j + m + 1, w);
                add ( (i - 1) * m + j + m + 1, (i - 1) * m + j, w);
            }
        /*
        for(int i = 1; i <= cnt; i++)
        {
            printf("%d %d %d
    ", e[i].to, e[i].len, e[i].next);
        }*/
        printf("%d", dinic());
        return 0;
    }
  • 相关阅读:
    nohub和 2>&1 &
    postman
    ximd 破解版
    B树和B+树的插入、删除图文详解
    漫画叙述B+树和B-树,很值得看!
    数据库 操作的几个问题记录
    推送实现 应用未启动情况下的自定义声音播放
    collectionView reloadData时 点击问题
    强制横屏或者竖屏
    wkWebView 或者 webView 在客户端隐藏某些布局的方法
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/9437534.html
Copyright © 2020-2023  润新知