题解

1 条题解

  • 0
    @ 2017-11-26 00:10:46

    Dinic

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 10010;
    struct edge { int to, cap, rev; };  // 存储边的结构体 (终点, 容量, 反向边)
    vector<edge> G[maxn];               // 邻接表
    int level[maxn], iter[maxn];        // level 为到源点的距离编号, iter 为当前弧
    
    // 添加一条从 from 到 to 的容量为 cap 的边
    void add_edge(int from, int to, int cap) {
        G[from].push_back((edge){to, cap, G[to].size()});
        G[to].push_back((edge){from, 0, G[from].size() - 1});
    }
    
    // 计算从源点出发的距离
    void bfs(int s) {
        memset(level, -1, sizeof(level));
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int i = 0; i < G[v].size(); i++) {
                edge &e = G[v][i];
                if (e.cap > 0 && level[e.to] == -1) {
                    level[e.to] = level[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    
    // dfs 寻找增广路
    int dfs(int v, int t, int f) {
        if (v == t) {
            return f;
        }
        for (int &i = iter[v]; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && level[v] < level[e.to]) {
                int d = dfs(e.to, t, min(f, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    
    // 求从 s 到 t 的最大流
    int dinic(int s, int t) {
        int flow = 0;
        while (true) {
            bfs(s);
            if (level[t] < 0) {
                return flow;
            }
            memset(iter, 0, sizeof(iter));
            int f;
            while ((f = dfs(s, t, 0x3f3f3f3f)) > 0) {
                flow += f;
            }
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        int n, m, s, t;
        cin >> n >> m >> s >> t;
        while (m--) {
            int from, to, cap;
            cin >> from >> to >> cap;
            add_edge(from, to, cap);
        }
        cout << dinic(s, t) << endl;
        return 0;
    }
    
  • 1

信息

难度
7
分类
网络流 点击显示
标签
递交数
101
已通过
6
通过率
6%
上传者