#1369 : 网络流一·Ford-Fulkerson算法 模板题

Posted stupid_one

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#1369 : 网络流一·Ford-Fulkerson算法 模板题相关的知识,希望对你有一定的参考价值。

http://hihocoder.com/problemset/problem/1369?sid=1108721

别人都说先学网络流再学二分图,但是我先学了二分图的,感觉网络流好高端啊。

首先对于原图,e[u][v],找到一条路径从be --> en后,要更新残余网络。

什么意思,其他东西自己百度。其实就是建反向边。

比如:

1 --> 2   w = 1

1 --> 3   w = 1

2 --> 3   w = 1

2 --> 4   w = 1

3 --> 4   w = 1

那么如果一开始网络流找到的增广路是1-->2-->3-->4后,整个图的最大流就是1,这样就错了。

应该是1-->2-->4和1-->3-->4,最大流是2.所以在2的时候,就要判断它应该流去那里了,如果每种情况都暴力一下, 复杂度是指数级。

但是如果建立反向边后,比如找到了1-->2-->3-->4,

则建立

4-->3  w = 1  

3-->2  w = 1 

2-->1  w = 1

这样做了的话,就可以继续找增广路,可以找到1-->3-->2-->4,贡献是1,

为什么可以这样呢?其实就是相当于把水流回去2那里,让2重新选。

#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 500 + 20;
int e[maxn][maxn];
int pre[maxn], flow[maxn];
int n, m;
int bfs(int be, int en) {
    queue<int> que;
    memset(pre, false, sizeof pre);
    pre[be] = -1, flow[be] = inf;
    que.push(be);
    while (!que.empty()) {
        int id = que.front();
        que.pop();
        if (id == en) break; // 找到增广路径
        for (int i = 1; i <= n; ++i) {
            if (pre[i] == 0 && e[id][i] > 0) {
                pre[i] = id;
                flow[i] = min(flow[id], e[id][i]);
                que.push(i);
            }
        }
    }
    if (pre[en] == 0) return -1;
    else return flow[en];
}
int maxFlow(int be, int en) {
    int sumFlow = 0;
    while (true) {
        int res = bfs(be, en);
        if (res == -1) break; //找不到增广路
        int u = pre[en], v = en;
        while (u != -1) {
            e[u][v] -= res;
            e[v][u] += res;
            v = u;
            u = pre[v];
        }
        sumFlow += res;
    }
    return sumFlow;
}
void work() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++i) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        e[u][v] += w;
    }
    cout << maxFlow(1, n) << endl;
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    work();
    return 0;
}

 

以上是关于#1369 : 网络流一·Ford-Fulkerson算法 模板题的主要内容,如果未能解决你的问题,请参考以下文章

hihoCoder 1369 网络流一·Ford-Fulkerson算法 (网络流学习#1 记录)

hihocoder网络流一·Ford-Fulkerson算法

hiho一下 第115周:网络流一?Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)

IO流一

·GAN·

《报任安书》文言文化常识闯关游戏·网络版