Cod sursa(job #2025170)

Utilizator MaarcellKurt Godel Maarcell Data 21 septembrie 2017 23:19:08
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.39 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <ctime>
#include <unordered_map>
#include <iomanip>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define all(v) (v).begin(),(v).end()

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pii;



const int inf = (1<<29);

struct MCMaxFlow{
    struct edge{
        int to,c,cst;
        edge(int to=0, int c=0, int cst=0) : to(to), c(c), cst(cst) {}
        edge(){}
    };

    vector<edge> e;
    set<pii> st;
    vi di;
    vector<vi> g;

    int n,S,F,flow,cflow;

    MCMaxFlow(int n, int S, int F){
        this->n=n;
        g.resize(n);
        di.resize(n);
        this->S=S,this->F=F;
    }

    void add_edge(int x, int y, int cp, int cst){
        edge e1(y,cp,cst);
        edge e2(x,0,-cst);
        g[x].pb(e.size());
        e.pb(e1);
        g[y].pb(e.size());
        e.pb(e2);
    }

    bool dijkstra(){
        vi d(n),p(n),pe(n);
        fill(all(d),inf);
        d[S]=0;
        st.clear();
        st.insert({0,S});
        vi real_d(n);

        while (!st.empty()){
            pii cr = *st.begin();
            st.erase(st.begin());

            int nod=cr.se;
            real_d[nod]=d[nod]-di[nod];

            for (int id : g[nod]){
                int nxt = e[id].to;
                int cst=d[nod]+e[id].cst-di[nod]+di[nxt];

                if (e[id].c && cst<d[nxt]){
                    if (d[nxt]!=inf) st.erase({d[nxt],nxt});
                    d[nxt] = cst;
                    p[nxt]=nod;
                    pe[nxt]=id;
                    st.insert({d[nxt],nxt});
                }
            }
        }

        di = real_d;
        if (d[F] == inf) return 0;

        int minv = inf,cr=0;
        for (cr=F; cr!=S; cr=p[cr])
            minv=min(minv,e[pe[cr]].c);

        flow+=minv;
        cflow += minv*real_d[F];

        for (cr = F; cr!=S; cr=p[cr]){
            e[pe[cr]].c-=minv;
            e[pe[cr]^1].c+=minv;
        }

        return 1;
    }

    int get_flow(){
        flow=cflow=0;
        bellman();

        while (dijkstra()) ;
        return flow;
    }

    void bellman(){
        fill(all(di),inf);
        di[S]=0;

        vi q,nq;
        vi v(n,0);
        q.pb(S);

        for (int i=1; i<=n; i++){
            nq.clear();
            for (int x : q){
                for (int id : g[x]){
                    int nxt = e[id].to;
                    if (e[id].c && e[id].cst+di[x]<di[nxt]){
                        di[nxt]=e[id].cst+di[x];

                        if (!v[nxt]) nq.pb(nxt);
                        v[nxt]=1;
                    }
                }
            }

            q.clear();
            for (int x : nq){
                v[x]=0;
                q.pb(x);
            }
        }

    }
};

int N,M,S,D;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    ifstream fin("fmcm.in");
    ofstream fout("fmcm.out");
    fin >> N >> M >> S >> D;

    MCMaxFlow mxf(N+1,S,D);
    while (M--){
        int x,y,c,z;
        fin >> x >> y >> c >> z;
        mxf.add_edge(x,y,c,z);
    }

    mxf.get_flow();
    fout << mxf.cflow << "\n";
    return 0;
}