• 最大流Dinic算法


    嘿嘿嘿,时隔不久又见到了DInic,再次回顾一下吧

     不过这次我倒是不想深究,而是想多做一些题,因为这几次比赛下来,算法不是重点,重点是题目如何转化,算法如何应用,这也是比赛为什么让你带着板子的原因吧,所以算法基本思想掌握了就好,不要去背,一看就能想通就行

    Dinic算法通过bfs优先的分层处理,加以当前弧的优化,使得dfs寻找 最大流的更多,不像ff算法dfs效率低下,通过分层使得dfs明确了寻找方向,当前弧的优化,使得dfs寻边效率大大提高

    Code

    一些基本操作

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <queue>
    #define inf (1 << 28)
    using namespace std;
    typedef long long ll;
    const int maxn = 220;
    const int maxm = 4e4 + 4e2;
    int n,m;
    struct node{
        int pre;
        int to,cost;
    }e[maxm];
    int id[maxn],cnt;
    //层数 int flor[maxn]; int cur[maxn];//DFS的优化遍历::当前弧优化 void add(int from,int to,int cost) { e[cnt].to = to; e[cnt].cost = cost; e[cnt].pre = id[from]; id[from] = cnt++; swap(from,to); e[cnt].to = to; e[cnt].cost = 0; e[cnt].pre = id[from]; id[from] = cnt++; }

     bfs分层处理

    其实明白了思路,这个很简单就能写出来

    int bfs(int s,int t)
    {
        memset(flor,0,sizeof(flor));
        queue < int > q;
            while(q.size())q.pop();
        flor[s] = 1;
        q.push(s);
    
        while(q.size())
        {
            int now = q.front();
            q.pop();
            for(int i = id[now];~i;i=e[i].pre)
            {
                int to = e[i].to;
                int cost = e[i].cost;
                if(flor[to] == 0 && cost > 0)
                {
                    flor[to] = flor[now] + 1;
                    q.push(to);
                    if(to == t)return 1;
                }
            }
        }
        return 0;
    }
    

     dfs当前弧度的优化

    dfs比较难懂,为什么要懂ff就是因为一切的算法都是以简单算法为基础的优化过来的

    value:是s - s’的最大流(起始点为s)

    ret:s' - t的残流(起始点为s’)

    一层一层的递归,value - ret就是最大流了,具体还是理解代码展现出的思想

    记得我第一次看的时候,dinic真的好绝望...看了n多篇博客,最后也没有

    int dfs(int s,int t,int value)
    {
        //ret表示目前流到s的最大流量,用来计算回溯的时候是否还有可行流
        int ret = value;
        if(s == t || value == 0)return value;
    
        int a;
    
        for(int &i = cur[s];~i;i = e[i].pre)
        {
            int to = e[i].to;
            int cost = e[i].cost;
            if(flor[to] == flor[s] + 1 && (a = dfs(to,t,min(ret,cost))))
            {
                e[i].cost -= a;
                e[i^1].cost += a;
                ret -= a;
                if(ret == 0)break;
            }
        }
        //s点后面没有可行的流了,flor[s] = 0就表示废掉了这个点
        if(ret == value) flor[s] = 0;
        return value - ret;
    }
    

     DInic算法就是基于bfs来dfs的

    int dinic(int s,int t)
    {
        ll ret = 0;
        while(bfs(s,t))
        {
            memcpy(cur,id,sizeof(id));
            ret += dfs(s,t,inf);
        }
        return ret;
    }
    

     其他的就简单啦

    void init()
    {
        memset(id,-1,sizeof(id));
        cnt = 0;
    }
    int main()
    {
        while(~scanf("%d%d",&m,&n))
        {
            init();
            int a,b,x;
            for(int i = 1;i <= m;++i)
            {
                scanf("%d%d%d",&a,&b,&x);
                add(a,b,x);
            }
            ll ret = dinic(1,n);
            printf("%lld
    ",ret);
        }
        return 0;
    }
    
  • 相关阅读:
    RAID技术
    敏捷开发
    如何写出高质量的代码?现在知道还不晚
    Java大型互联网架构技术经验
    Chrome精品插件
    2018 java BAT最新面试宝典
    Java成神之路(2018版)
    三分钟读懂摘要算法
    我的Mac应用清单
    事务隔离级别
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/9682044.html
Copyright © 2020-2023  润新知