zoukankan      html  css  js  c++  java
  • 如何写出一份简单能用的费用流代码

    如何写出一份简单能用的费用流代码

    标签: 笔记


    如果你已经学会了Dinic最大流,那么在Dinic的基础上稍加修改,就可以得到一份费用流代码。

    主要的修改在于把原来的BFS“分层”函数改成一个SPFA(就是“队列优化的Bellman-Ford算法”——如果你喜欢这个名字)。原先的dis表示距离源点的边数,相当于每条边费用是1的时候的距离源点最短路;现在的dis则是每条边带费用时的最短路。

    原来在进行增广的时候,要判断 dis[v] > dis[u],而现在则判断 dis[v] == dis[u] + w[e]。

    当增广的时候找到汇点des,则总费用 += dis[des] * flow。

    模板(POJ 2135):

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    typedef long long ll;
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define INF 0x3f3f3f3f
    template <class T>
    void read(T &x){
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x){
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 2005, M = 200005;
    int n, m, src, des, ans, dis[N];
    int ecnt = 1, adj[N], cur[N], nxt[M], go[M], cap[M], cost[M];
    bool inq[N], vis[N];
    queue <int> que;
    void ADD(int u, int v, int _cap, int _cost){
        go[++ecnt] = v;
        nxt[ecnt] = adj[u];
        adj[u] = ecnt;
        cap[ecnt] = _cap;
        cost[ecnt] = _cost;
    }
    void add(int u, int v, int _cap, int _cost){
        ADD(u, v, _cap, _cost);
        ADD(v, u, 0, -_cost);
    }
    bool bfs(){
        for(int i = 1; i <= des; i++)
            cur[i] = adj[i], dis[i] = INF, vis[i] = 0;
        dis[src] = 0, inq[src] = 1, que.push(src);
        while(!que.empty()){
            int u = que.front();
            inq[u] = 0, que.pop();
            for(int e = adj[u], v; e; e = nxt[e])
                if(cap[e] && dis[u] + cost[e] < dis[v = go[e]]){
                    dis[v] = dis[u] + cost[e];
                    if(!inq[v]) inq[v] = 1, que.push(v);
                }
        }
        return dis[des] < INF;
    }
    int dfs(int u, int flow){
        if(u == des) return ans += flow * dis[u], flow;
        vis[u] = 1;
        int ret = 0, delta;
        for(int &e = cur[u], v; e; e = nxt[e])
            if(cap[e] && !vis[v = go[e]] && dis[u] + cost[e] == dis[v]){
                delta = dfs(v, min(flow - ret, cap[e]));
                if(delta){
                    cap[e] -= delta;
                    cap[e ^ 1] += delta;
                    ret += delta;
                    if(ret == flow) break;
                }
            }
        return ret;
    }
    int main(){
        read(n), read(m);
        for(int i = 1, u, v, w; i <= m; i++){
            read(u), read(v), read(w);
            add(u, v, 1, w), add(v, u, 1, w);
        }
        src = n + 1, des = n + 2;
        add(src, 1, 2, 0);
        add(n, des, 2, 0);
        while(bfs()) dfs(src, INF);
        write(ans), enter;
        return 0;
    }
    
  • 相关阅读:
    P1144 最短路计数 题解 最短路应用题
    C++高精度加减乘除模板
    HDU3746 Teacher YYF 题解 KMP算法
    POJ3080 Blue Jeans 题解 KMP算法
    POJ2185 Milking Grid 题解 KMP算法
    POJ2752 Seek the Name, Seek the Fame 题解 KMP算法
    POJ2406 Power Strings 题解 KMP算法
    HDU2087 剪花布条 题解 KMP算法
    eclipse创建maven项目(详细)
    maven的作用及优势
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/POJ2135.html
Copyright © 2011-2022 走看看