• P3381 [模板] 最小费用最大流


    EK  + dijkstra (2246ms) 开氧气(586ms)

    dijkstra的势 可以处理负权 https://www.luogu.org/blog/28007/solution-p3381

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 1e9;
    
    int n, m, s, t, cnt;
    
    struct node {
        int to, nex, val, cost;
    }E[100005];
    int head[5005];
    
    void addedge(int x, int y, int va, int cos) {
        E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
    }
    
    struct no1 {
        int to, edge;
    }pre[5005];
    
    struct no2 {
        int d, id;
        friend bool operator < (no2 A, no2 B) {
            return A.d > B.d;
        }
    };
    
    int dis[5005];
    int h[5005];
    bool dij() {
    
        for(int i = 1; i <= n; i++) dis[i] = INF;
        priority_queue<no2> que;
    
        dis[s] = 0;
        que.push((no2){0, s});
    
        while(!que.empty()) {
            no2 u = que.top();
            que.pop();
            if(dis[u.id] < u.d) continue;
    
            for(int i = head[u.id]; i; i = E[i].nex) {
                int v = E[i].to;
                if(E[i].val > 0 && dis[v] + h[v] > dis[u.id] + E[i].cost + h[u.id]) {
                    dis[v] = dis[u.id] + E[i].cost + h[u.id] - h[v];
                    pre[v].to = u.id;
                    pre[v].edge = i;
                    que.push((no2){dis[v], v});
                }
            }
        }
        if(dis[t] != INF) return true;
        else return false;
    }
    
    int ans, cos1;
    void EK() {
        ans = cos1 = 0;
    
        while(dij()) {
            int mi = INF;
            for(int i = t; i != s; i = pre[i].to) {
                mi = min(mi, E[pre[i].edge].val);
            }
            for(int i = t; i != s; i = pre[i].to) {
                E[pre[i].edge].val -= mi;
                E[pre[i].edge ^ 1].val += mi;
            }
            for(int i = 1; i <= n; i++) h[i] += dis[i];
            ans += mi;
            cos1 += mi * h[t];
        }
    }
    
    
    int main() {
        scanf("%d%d%d%d", &n, &m, &s, &t);
        cnt = 1;
    
        for(int i = 1; i <= m; i++) {
            int a, b, c, d;
            scanf("%d%d%d%d", &a, &b, &c, &d);
            addedge(a, b, c, d);
            addedge(b, a, 0, -d);
        }
        EK();
        printf("%d %d
    ", ans, cos1);
        return 0;
    }
    View Code

    EK + spfa (1775ms) 开氧气(1398ms)

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 1e9;
    
    int n, m, s, t, cnt;
    
    struct node {
        int to, nex, val, cost;
    }E[100005];
    int head[5005];
    
    void addedge(int x, int y, int va, int cos) {
        E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
    }
    
    struct no1 {
        int to, edge;
    }pre[5005];
    
    int dis[5005];
    int vis[5005];
    
    bool spfa() {
        memset(vis, 0, sizeof(vis));
        memset(dis, 0x3f, sizeof(dis));
    
        queue<int> que;
        que.push(s);
        vis[s] = 1;
        dis[s] = 0;
        while(!que.empty()) {
            int u = que.front();
            vis[u] = 0;
            que.pop();
    
            for(int i = head[u]; i; i = E[i].nex) {
                int v = E[i].to;
                if(E[i].val > 0 && dis[v] > dis[u] + E[i].cost) {
                    dis[v] = dis[u] + E[i].cost;
                    pre[v].to = u;
                    pre[v].edge = i;
                    if(!vis[v]) {
                        vis[v] = 1;
                        que.push(v);
                    }
                }
            }
        }
        if(dis[t] != 0x3f3f3f3f) return true;
        else return false;
    }
    
    int ans, cos1;
    void EK() {
        ans = cos1 = 0;
    
        while(spfa()) {
            int mi = INF;
            for(int i = t; i != s; i = pre[i].to) {
                mi = min(mi, E[pre[i].edge].val);
            }
            for(int i = t; i != s; i = pre[i].to) {
                E[pre[i].edge].val -= mi;
                E[pre[i].edge ^ 1].val += mi;
            }
            ans += mi;
            cos1 += mi * dis[t];
        }
    }
    
    
    int main() {
        scanf("%d%d%d%d", &n, &m, &s, &t);
        cnt = 1;
    
        for(int i = 1; i <= m; i++) {
            int a, b, c, d;
            scanf("%d%d%d%d", &a, &b, &c, &d);
            addedge(a, b, c, d);
            addedge(b, a, 0, -d);
        }
        EK();
        printf("%d %d
    ", ans, cos1);
        return 0;
    }
    View Code

    Dinic多路增广 + 弧优化 + spfa (1744ms) 

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 1e9;
    
    int n, m, s, t, cnt;
    int maxflow, mincost;
    
    struct node {
        int to, nex, val, cost;
    }E[100005];
    int head[5005];
    int cur[5005];
    
    void addedge(int x, int y, int va, int cos) {
        E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va; E[cnt].cost = cos;
    }
    
    struct no1 {
        int to, edge;
    }pre[5005];
    
    int dis[5005];
    int inque[5005];
    int vis[5005];
    
    bool spfa() {
        for(int i = 1; i <= n; i++) inque[i] = 0, dis[i] = 0x3f3f3f3f, cur[i] = head[i], vis[i] = 0;
    
        queue<int> que;
        que.push(s);
        inque[s] = 1;
        dis[s] = 0;
        while(!que.empty()) {
            int u = que.front();
            inque[u] = 0;
            que.pop();
    
            for(int i = head[u]; i; i = E[i].nex) {
                int v = E[i].to;
                if(E[i].val > 0 && dis[v] > dis[u] + E[i].cost) {
                    dis[v] = dis[u] + E[i].cost;
                    pre[v].to = u;
                    pre[v].edge = i;
                    if(!inque[v]) {
                        inque[v] = 1;
                        que.push(v);
                    }
                }
            }
        }
        if(dis[t] != 0x3f3f3f3f) return true;
        else return false;
    }
    
    int dfs(int x, int flow) {
        if(x == t) {
            vis[x] = 1;
            maxflow += flow;
            return flow;
        }
    
        vis[x] = 1;
        int used = 0;
        int rflow = 0;
        for(int i = cur[x]; i; i = E[i].nex) {
            cur[x] = i;
            int v = E[i].to;
            if(E[i].val > 0 && dis[v] == dis[x] + E[i].cost && (!vis[v] || v == t)) {
                if(rflow = dfs(v, min(flow - used, E[i].val))) {
                    used += rflow;
                    E[i].val -= rflow;
                    E[i ^ 1].val += rflow;
                    mincost += E[i].cost * rflow;
                    if(used == flow) break;
                }
            }
        }
        return used;
    }
    
    void dinic() {
        maxflow = mincost = 0;
        while(spfa()) {
            vis[t] = 1;
            while(vis[t]) {
                memset(vis, 0, sizeof(vis));
                dfs(s, INF);
            }
        }
    }
    
    int main() {
        scanf("%d%d%d%d", &n, &m, &s, &t);
        cnt = 1;
    
        for(int i = 1; i <= m; i++) {
            int a, b, c, d;
            scanf("%d%d%d%d", &a, &b, &c, &d);
            addedge(a, b, c, d);
            addedge(b, a, 0, -d);
        }
        dinic();
        printf("%d %d
    ", maxflow, mincost);
        return 0;
    }
    View Code
  • 相关阅读:
    [java初探06]__排序算法的简单认识
    [java初探05]__数组的简单认识及Arrays类的常用方法
    [java工具类01]__构建格式化输出日期和时间的工具类
    [Java初探04]__字符串(String类)相关
    [Java初探实例篇02]__流程控制语句知识相关的实例练习
    【Java初探03】——流程控制语句
    iOS ipv6 被拒
    iOS工程中如何去掉第三方的警告
    iOS面试准备之思维导图(转)
    UML图基本类型
  • 原文地址:https://www.cnblogs.com/lwqq3/p/11143469.html
Copyright © 2020-2023  润新知