网络流 && 费用流 模板

网络最大流

#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define inf (0x3f3f3f3f)

using namespace std;

const int maxn = 1e4 + 10, maxm = 1e5 + 10;
int n, m, s, t;

namespace Maxflow {
    int to[maxm << 1], head[maxn], nxt[maxm <<1], w[maxm << 1], e = 1;
    int dis[maxn];

    void add(int x, int y, int z) {
        to[++ e] = y;
        nxt[e] = head[x];
        head[x] = e;
        w[e] = z;
        if(z) add(y, x, 0);
    }

    bool bfs() {
        queue<int> q;
        memset(dis, 0, sizeof(dis));
        dis[s] = 1, q.push(s);
        while(!q.empty()) {
            int k = q.front(); q.pop();
            go(k, i) 
                if(w[i] && !dis[to[i]]) {
                    dis[to[i]] = dis[k] + 1;
                    q.push(to[i]);
                }
        }
        return dis[t];
    }

    int dfs(int x, int flow) {
        if(x == t || !flow) return flow;
        int used = 0;
        go(x, i) 
            if(dis[to[i]] == dis[x] + 1) {
                int di = dfs(to[i], min(flow, w[i]));
                w[i] -= di, w[i ^ 1] += di;
                flow -= di, used += di;
                if(!flow) break;
            }
        return used;
    }

    int dinic() {
        int res = 0;
        while(bfs()) 
            res += dfs(s, inf);
        return res;
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("Maxflow.in", "r", stdin);
    freopen("Maxflow.out", "w", stdout);
#endif
    int x, y, z;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    For(i, 1, m) {
        scanf("%d%d%d", &x, &y, &z);
        Maxflow::add(x, y, z);
    }       
    printf("%d\n", Maxflow::dinic());
    return 0;
}

最小费用最大流

#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])
#define inf (0x3f3f3f3f)

using namespace std;

const int maxn = 1e4 + 10, maxm = 1e5 + 10;
int n, m, s, t, cost;

namespace Mincost_Maxflow {
    int to[maxm << 1], head[maxn], nxt[maxm << 1], v[maxm << 1], w[maxm << 1], e = 1;
    int dis[maxn], vis[maxn];

    void add(int x, int y, int z, int val) {
        to[++ e] = y;
        nxt[e] = head[x];
        head[x] = e;
        w[e] = z;
        v[e] = val;
        if(z) add(y, x, 0, -val);
    }

    bool SPFA() {
        queue<int> q;
        memset(dis, inf, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        dis[s] = 0, vis[s] = 1, q.push(s);
        while(!q.empty()) {
            int k = q.front(); q.pop();
            go(k, i) 
                if(w[i] && dis[to[i]] > dis[k] + v[i]) {
                    dis[to[i]] = dis[k] + v[i];
                    if(!vis[to[i]]) {
                        vis[to[i]] = true;
                        q.push(to[i]);
                    }
                }
            vis[k] = false;
        }
        return dis[t] != inf;
    }

    int dfs(int x, int flow) {
        vis[x] = flow;
        if(x == t || !flow) 
            return flow;
        int used = 0;
        go(x, i) 
            if(dis[to[i]] == dis[x] + v[i] && !vis[to[i]]) {
                int di = dfs(to[i], min(flow, w[i]));
                w[i] -= di, w[i ^ 1] += di;
                flow -= di, used += di, cost += di * v[i];
                if(!flow) break;
            }
        return used;
    }

    int dinic() {
        int res = 0;
        while(SPFA()) {
            vis[t] = true;
            while(vis[t]) {
                memset(vis, 0, sizeof(vis));
                res += dfs(s, inf);
            }
        }
        return res;
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("Mincost_Maxflow.in", "r", stdin);
    freopen("Mincost_Maxflow.out", "w", stdout);
#endif
    int x, y, z, val;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    For(i, 1, m) {
        scanf("%d%d%d%d", &x, &y, &z, &val);
        Mincost_Maxflow::add(x, y, z, val);
    }
    printf("%d ", Mincost_Maxflow::dinic());
    printf("%d\n", cost);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lunch__/article/details/81280332
今日推荐