zoukankan      html  css  js  c++  java
  • 网络流-费用流zkw算法

    基础费用流

    进行SPFA每次对残余网络求最短路,记录前驱,然后跑这条增广路,更新答案,直到源点和汇点不连通位置

    改良

    我们可以类似dinic,在spfa求完每个点到源点的距离之后,再像dinic一样进行增广,这样就能多路增广,并且还可以加当前弧优化。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 5e3 + 5;
    const int INF = 0x3f3f3f3f;
    
    int n, m;
    
    struct Edge{
        int to, val, cost;
        Edge *next, *ops;
        Edge(int to, int val, int cost, Edge *next): to(to), val(val), cost(cost), next(next){}
    };
    
    Edge *head[MAXN];
    
    void AddEdge(int u, int v, int w, int c) {
        head[u] = new Edge(v, w, c, head[u]);
        head[v] = new Edge(u, 0, -c, head[v]);
        head[u]->ops = head[v]; head[v]->ops = head[u];
    }
    
    namespace zkw{
        int s, t, ans, res;
        int dis[MAXN];
        bool vis[MAXN];
        //Edge *cur[MAXN];
        bool Spfa() {
            memset(vis, false, sizeof vis);
            memset(dis, 0x3f, sizeof dis);
            deque<int> q;
            q.push_back(s);
            vis[s] = true; dis[s] = 0;
            while (!q.empty()) {
                int u = q.front(); q.pop_front(); vis[u] = false;
                for (Edge *e = head[u]; e; e = e->next) {
                    int v = e->to;
                    if (e->val > 0 && dis[u] + e->cost < dis[v]) {
                        dis[v] = dis[u] + e->cost;
                        if (!vis[v]) {
                            vis[v] = true;
                            if (!q.empty() && dis[v] < dis[q.front()]) q.push_front(v);
                            else q.push_back(v);
                        }
                    }
                }
            }
            return dis[t] < INF;
        }
        
        int Dfs(int u, int flow) {
            if (u == t) {
                vis[u] = true;
                res += flow;
                return flow;
            }
            int used = 0; vis[u] = true;
            for (Edge *e = head[u]; e; e = e->next) {
                int v = e->to;
                if ((!vis[v] || v == t) && e->val && dis[u] + e->cost == dis[v]) {
                    int mi = Dfs(v, min(e->val, flow - used));
                    if (mi) {
                        e->val -= mi;
                        e->ops->val += mi;
                        ans += e->cost * mi;
                        used += mi;
                    }
                    if (used == flow) break;
                }
            }
            return used;
        }
        
        void Work() {
            res = 0; ans = 0;
            while (Spfa()) {
                vis[t] = true;
                while (vis[t]) {
                    memset(vis, false, sizeof vis);
                    Dfs(s, INF);
                }
            }
        }
    }
    
    int main() {
        cin >> n >> m >> zkw :: s >> zkw :: t;
        for (int i = 1; i <= m; i++) {
            int u, v, w, c;
            cin >> u >> v >> w >> c;
            AddEdge(u, v, w, c);
        }
        zkw :: Work();
        cout << zkw :: res << ' ' << zkw :: ans << endl;
        return 0;
    }
    

      

  • 相关阅读:
    python重载四则运算符及输出格式设置
    hdu 1069 Monkey and Banana
    python特殊函数 __len__(self):
    selective_search_rcnn.m中代码
    用list去初始化numpy的array数组 numpy的array和python中自带的list之间相互转化
    把字符串转化为整数
    这就是那个feature map256 256向量
    对faster rcnn代码讲解的很好的一个
    input_shape { dim: 1 dim: 3 dim: 224 dim: 224 }
    faster rcnn的改进方向
  • 原文地址:https://www.cnblogs.com/Juruo1103/p/10500172.html
Copyright © 2011-2022 走看看