• 最大流_Edmonds-Karp算法


    最大流_Edmonds-Karp算法

    最大流问题是指求源点s到汇点d的最大流量的一类问题,下面是基于增广路的Edmonds-Karp算法

    const int INF = 0x3f3f3f3f;
    const int MAX = 205;
    struct edge {
        int from;  //头
        int to;    //目标
        int cap;   //容量
        int flow;  //流量
        edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {}
    };
    struct edmondKarp {
        int n;
        int m;
        vector<edge> edges;
        vector<int> G[MAX];  //邻接表
        int a[MAX];          //起点到i的可改进量
        int p[MAX];          //起点的前驱节点
    
        void init(int n) {
            for (int i = 0; i < n; i++) {
                G[i].clear();
            }
            edges.clear();
        }
    
        void AddEdge(int from, int to, int cap) {
            edges.push_back(edge(from, to, cap, 0));
            edges.push_back(edge(to, from, 0, 0));  //反向边
            m = edges.size();
            G[from].push_back(m - 2);
            G[to].push_back(m - 1);
        }
    
        int max_flow(int s, int t) {
            int flow = 0;
            while (true) {
                memset(a, 0, sizeof(a));
                queue<int> q;
                q.push(s);
                a[s] = INF;
                while (!q.empty()) {
                    int x = q.front();
                    q.pop();
                    for (int i = 0; i < G[x].size(); i++) {
                        edge& e = edges[G[x][i]];
                        //如果e边的目标点没被优化过并且有优化空间
                        if (!a[e.to] && e.cap > e.flow) {
                            p[e.to] = G[x][i];
                            //值为前驱节点或者容量限制
                            a[e.to] = min(a[x], e.cap - e.flow);
                            q.push(e.to);
                        }
                    }
                    //优化到汇点了
                    if (a[t]) break;
                }
                //汇点没被优化,说明已经优化到头了
                if (!a[t]) break;
                //从后向前遍历
                for (int u = t; u != s; u = edges[p[u]].from) {
                    //出边的流增加
                    edges[p[u]].flow += a[t];
                    //入边的流减小
                    edges[p[u] ^ 1].flow -= a[t];
                }
                //得到的a[t]是整条路的最小残量
                flow += a[t];
            }
            return flow;
        }
    };
    
  • 相关阅读:
    551. 学生出勤纪录 I
    387. 字符串中的第一个唯一字符
    剑指OFFER 字符串的排列
    剑指OFFER 斐波那契数列
    剑指OFFER 重建二叉树
    剑指OFFER 二维数组中的查找
    剑指OFFER 和为S的两个数字
    剑指OFFER 左旋转字符串
    剑指OFFER 合并两个排序的链表
    剑指OFFER 从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/hermitgreen/p/12652621.html
Copyright © 2020-2023  润新知