码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2017-06-03 09:48:40      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:using   flow   .com   end   ==   name   ems   scan   nbsp   

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算法 模板题

标签:using   flow   .com   end   ==   name   ems   scan   nbsp   

原文地址:http://www.cnblogs.com/liuweimingcprogram/p/6935694.html

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