码迷,mamicode.com
首页 > 其他好文 > 详细

网络流

时间:2020-05-04 00:40:18      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:增加   dfs   clear   number   oid   ack   front   color   set   

//网络流s
const int INF = 0x3f3f3f3f, maxn = 210;

struct E {
    int u, v, flow;
    E(int u = 0, int v = 0, int flow = 0): u(u), v(v), flow(flow) {}
} edg[maxn * maxn];

struct Dinic{
    int cnt_edg, S, T;
    vector<int> edge[maxn]; // 边集
    int dis[maxn];//距源点距离,分层图
    int current[maxn];//当前弧
    void ini()
    {
        for(int i=0;i<maxn;i++)
            edge[i].clear();
        memset(edg, 0, sizeof edg);
        cnt_edg=0;
    }
    void addedg(int u, int v, int flow) {
        
        edge[u].push_back(cnt_edg);
        edg[cnt_edg++] = E(u, v, flow); // 正向边
        edge[v].push_back(cnt_edg);
        edg[cnt_edg++] = E(v, u, 0); // 反向边容量为0
        // 正向边下标通过异或就得到反向边下标, 2 ^ 1 == 3 ; 3 ^ 1 == 2
    }

    bool bfs() {
        queue<int> q;
        q.push(S);
        memset(dis, -1, sizeof(dis));
        dis[S] = 0;
        while (!q.empty()) {
            int index = q.front();
            q.pop();
            int sz = int(edge[index].size());
            for (int i = 0; i < sz; i++) {
                E &e = edg[edge[index][i]];
                if (e.flow > 0) {
                    if (dis[e.v] < 0) {
                        dis[e.v] = dis[index] + 1;
                        q.push(e.v);
                    }
                }
            }
        }
        return bool(~dis[T]); // 返回是否能够到达汇点
    }

    int dfs(int index, int maxflow) {
        if (index == T)
            return maxflow;
        // i = current[index] 当前弧优化
        int sz = int(edge[index].size());
        for (int i = current[index], number; number = edge[index][i], i < sz; i++) {
            current[index] = i;
            E &e = edg[number];
            if (dis[e.v] == dis[index] + 1 && e.flow > 0) {
                int flow = dfs(e.v, min(maxflow, e.flow));
                if (flow != 0) {
                    e.flow -= flow; // 正向边流量降低
                    edg[number ^ 1].flow += flow; // 反向边流量增加
                    return flow;
                }
            }
        }
        return 0; // 找不到增广路 退出
    }

    int dinic() {
        int ans = 0;
        while (bfs()) {// 建立分层图
            int flow;
            memset(current, 0, sizeof(current)); // BFS后应当清空当前弧数组
            while (bool(flow = dfs(S, INF))) // 一次BFS可以进行多次增广
                ans += flow;
        }
        return ans;
    }
}D;

//网络流e

 

网络流

标签:增加   dfs   clear   number   oid   ack   front   color   set   

原文地址:https://www.cnblogs.com/King-of-Dark/p/12824839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!