Cod sursa(job #2930744)

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


    struct edge {
        long long v,cap, flow,cost;
    };
    long long n;
    vector<edge> e;
    vector<long long>g[N];
    long long dist[N], pot[N];
    long long f[N];
    bool vis[N];
    long long 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(ll u, ll v, ll cap, ll cost) {
        ll 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<long long, long long> solve(ll s, ll t) {
        ll flow = 0;
        long long cost = 0;
        while(true) {
            memset(dist,INF,sizeof(dist));
            memset(vis, false,sizeof(vis));
            dist[s] = 0;
            f[s] = INF;
            if(n2dijkstra) {
                while(true) {
                    ll x = -1; ll d = INF;
                    for(ll i = 1; i <= n; i++) {
                        if(!vis[i] && dist[i] < d) {
                            x = i;
                            d = dist[x];
                        }
                    }
                    if(x == -1) break;
                    vis[x] = true;
                    for(ll i : g[x]) {
                        ll 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<ll, ll>, vector<pair<ll, ll> >, greater<pair<ll,ll> > > Q;
                Q.push({0, s});
                while(!Q.empty()) {
                    ll d; ll x;
                    tie(d, x) = Q.top(); Q.pop();
                    if(vis[x]) continue;
                    vis[x] = true;
                    for(ll i : g[x]) {
                        ll 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(ll i = 1; i <= n; i++) {
                dist[i] += pot[i] - pot[s];
            }
            cost += 1ll*dist[t] * f[t];
            flow += f[t];
            ll 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()
{
    ll 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;
}