Cod sursa(job #2930738)

Utilizator mihneazzzMacovei Daniel mihneazzz Data 29 octombrie 2022 14:34:03
Problema Flux maxim de cost minim Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
#include <bits/stdc++.h>
#define N 405
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");


    struct edge {
        int v;
        int cap, flow;
        int cost;
    };
    int n;
    vector<edge> e;
    vector<int>g[N];
    int dist[N], pot[N];
    int f[N];
    bool vis[N];
    int par[N];
    bool n2dijkstra = false;
    ///mcmf(int n) : n(n), g(n), dist(n), pot(n), f(n), vis(n), par(n) {}
    void add_edge(int u, int v, int cap, int cost) {
        int k = e.size();
        e.push_back({v, cap, 0, cost});
        e.push_back({u, cap, cap, -cost});
        g[u].push_back(k);
        g[v].push_back(k ^ 1);
    }
    pair<int, long long> solve(int s, int t) {
        int flow = 0;
        long long cost = 0;
        while(true) {
            memset(dist,INF,sizeof(dist));
            memset(vis, false,sizeof(vis));
            dist[s] = 0;
            f[s] = numeric_limits<int>::max();
            if(n2dijkstra) {
                while(true) {
                    int x = -1; int d = numeric_limits<int>::max();
                    for(int i = 0; i < n; i++) {
                        if(!vis[i] && dist[i] < d) {
                            x = i;
                            d = dist[x];
                        }
                    }
                    if(x == -1) break;
                    vis[x] = true;
                    for(int i : g[x]) {
                        int d2 = d + e[i].cost + pot[x] - pot[e[i].v];
                        if(!vis[e[i].v] && e[i].flow < e[i].cap && d2 < dist[e[i].v]) {
                            dist[e[i].v] = d2;
                            f[e[i].v] = min(f[x], e[i].cap - e[i].flow);
                            par[e[i].v] = i;
                        }
                    }
                }
            }else {
                priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int,int> > > Q;
                Q.push({0, s});
                while(!Q.empty()) {
                    int d; int x;
                    tie(d, x) = Q.top(); Q.pop();
                    if(vis[x]) continue;
                    vis[x] = true;
                    for(int i : g[x]) {
                        int d2 = d + e[i].cost + pot[x] - pot[e[i].v];
                        if(!vis[e[i].v] && e[i].flow < e[i].cap && d2 < dist[e[i].v]) {
                            dist[e[i].v] = d2;
                            f[e[i].v] = min(f[x], e[i].cap - e[i].flow);
                            par[e[i].v] = i;
                            Q.push({d2, e[i].v});
                        }
                    }
                }
            }
            if(!vis[t]) break;
            for(int i = 1; i <= n; i++) {
                dist[i] += pot[i] - pot[s];
            }
            cost += 1ll*dist[t] * f[t];
            flow += f[t];
            int x = t;
            while(x != s) {
                e[par[x]].flow += f[t];
                e[par[x] ^ 1].flow -= f[t];
                x = e[par[x] ^ 1].v;
            }
            swap(dist,pot);
        }
        return {flow, cost};
    }

int main()
{
    int i,x,y,c,z,m,s,t;
    fin>>n>>m>>s>>t;
    while(m--)
    {
        fin>>x>>y>>c>>z;
        add_edge(x,y,c,z);
    }
    fout<<solve(s,t).second;
    return 0;
}