zoukankan      html  css  js  c++  java
  • 初识最大流

    Dinic算法:

    while(能够分层)

    {

      分层;

      dfs增广;

    }

    分层:即源点为0层,能一步到达的点为第一层,二步到达的点为第二层......(边容量为0即为不可达)。

    dfs增广:按照层次从源点搜索一条可行流到汇点,减去可行流得到残余网络,然后回溯,接着在残余网络上寻找可行流,直到回溯到0层不能找到可行流。

    残余网络:在图上减去可行流,相应地增加反向流,就成残余网络了。反向流即有取消流的作用,和匈牙利算法的将原已经建立的匹配回撤操作类似。

    const int MAX_N = 100;  
    const int MAX_M = 10000;  
    const int INF = 1000000000;  
    struct edge {
        int v, c, next;  //v是右端点,c是容量 
    } e[MAX_M];
    int p[MAX_N], eid;
    void init() {
        memset(p, -1, sizeof(p));
        eid = 0;
    }
    void insert(int u, int v, int c) {  
        e[eid].v = v;
        e[eid].c = c;
        e[eid].next = p[u];
        p[u] = eid++;
    }
    void addedge(int u, int v, int c) {  
        insert(u, v, c);
        insert(v, u, 0);  
    }
    int S, T;  
    int d[MAX_N];  
    bool CountLayer() {  //分层 
        memset(d, -1, sizeof(d));
        queue<int> q;
        q.push(S);
        d[S] = 0;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            for (int i = p[u]; i != -1; i = e[i].next) {
                int v = e[i].v;
                if (e[i].c > 0 && d[v] == -1) {
                    q.push(v);
                    d[v] = d[u] + 1;
                }
            }
        }
        return (d[T] != -1); //源点是否能到达汇点,即分层是否成功 
    }
    
    int dfs(int u, int flow) {  //flow为前面层次流入u点可行流最大流量 ,源点即为正无穷 
        if (u == T) {
            return flow;
        }
        int res = 0;
        for (int i = p[u]; i != -1; i = e[i].next) {
            int v = e[i].v;
            if (e[i].c > 0 && d[u] + 1 == d[v]) {
                int tmp = dfs(v, min(flow, e[i].c));  
                flow -= tmp;
                e[i].c -= tmp;
                res += tmp;
                e[i ^ 1].c += tmp;  
                if (flow == 0) {  
                    break;
                }
            }
        }
        if (res == 0) {  //不能从该点搜索到可行流了,标志为-1 
            d[u] = -1;
        }
        return res;
    }
    
    int maxflow() {  
        int res = 0;
        while (CountLayer()) {
            res += dfs(S, INF);  
        }
        return res;
    }
  • 相关阅读:
    elementUI Select 下拉框列表分两列展示
    radio切换后,表格数据记住之前选中的行
    vue 子组件和父组件生命周期顺序
    vue-router理解
    vuex理解
    实验四 决策树算法及应用
    实验三 朴素贝叶斯算法及应用
    实验二 K-近邻算法及应用
    词法分析可视化MFC
    SEO工具ahrefs各参数详解
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/8973979.html
Copyright © 2011-2022 走看看