Cod sursa(job #2527757)

Utilizator AlexBolfaAlex Bolfa AlexBolfa Data 20 ianuarie 2020 20:55:23
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.47 kb
#include <bits/stdc++.h>
#define NMAX (int)(4e3+4)
#define MMAX (int)(3e4+4)
#define pb emplace_back
#define ft first
#define sd second
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
typedef pair <int, int> pairINT;
typedef long long ll;
struct edge{
    int x,y,cap,cost,flow;
    edge(int a,int b,int c,int d){
        x=a;
        y=b;
        cap=c;
        cost=d;
        flow=0;
    }
    edge(){

    }
};
class Network{
    public:
        int n;
        void add_edge(int x,int y,int cap,int cost){
            g[x].pb(++id);
            e[id]=edge(x, y, cap, cost);

            g[y].pb(++id);
            e[id]=edge(y, x, 0, -cost);
        }
        int GetFlow(int s, int d){
            int add,sol;
            bellman_ford(s);
            while(dijkstra(s, d)){
                add=1e9;
                for(int node=d;tata[node];node=e[tata[node]].x)
                    add=min(add, e[tata[node]].cap - e[tata[node]].flow);

                for(int node=d;tata[node];node=e[tata[node]].x){
                    e[tata[node]].flow+=add;
                    e[tata[node]^1].flow-=add;

                    sol+=add*e[tata[node]].cost;
                }
            }
            return sol;
        }
    private:
        bool dijkstra(int node, int fin){
            priority_queue <pairINT, vector <pairINT>,greater <pairINT>> pq;
            memset(cost, 0x3f, sizeof cost);
            tata[fin]=0;
            int temp;

            cost[node]=0;
            pq.push({0, node});
            while(!pq.empty()){
                node=pq.top().sd;
                temp=pq.top().ft;
                pq.pop();

                if(node == fin) continue;
                if(temp > cost[node]) continue;

                for(auto it:g[node]){
                    temp=cost[node] + dist[node] + e[it].cost - dist[e[it].y];
                    if(e[it].flow != e[it].cap && cost[e[it].y] > temp){
                        cost[e[it].y]=temp;
                        tata[e[it].y]=it;
                        pq.push({cost[e[it].y], e[it].y});
                    }
                }
            }
            for(int i=1;i<=n;++i)
                dist[i]+=cost[i];
            return tata[fin];
        }
        void bellman_ford(int node){
            priority_queue <pairINT, vector <pairINT>,greater <pairINT>> pq;
            bitset <NMAX> inQue;
            memset(dist, 0x3f, sizeof dist);
            inQue.reset();

            dist[node]=0;
            pq.push({0, node});
            while(!pq.empty()){
                node=pq.top().sd;
                pq.pop();
                inQue[node]=0;

                for(auto it:g[node]){
                    if(e[it].cap && dist[e[it].y] > dist[node] + e[it].cost){
                        if(!inQue[e[it].y])
                            pq.push({dist[e[it].y], e[it].y});
                        dist[e[it].y]=dist[node] + e[it].cost;
                        pq.push({dist[e[it].y], e[it].y});
                        inQue[e[it].y]=1;
                    }
                }
            }
        }
        int id=1;
        int dist[NMAX],tata[NMAX],cost[NMAX];
        vector <int> g[NMAX];
        edge e[MMAX];
};
Network G;

int main(){
    int n,m,s,t;
    fin>>n>>m>>s>>t;
    G.n = n;
    for(int i=0,x,y,c,k;i<m;++i){
        fin>>x>>y>>c>>k;
        G.add_edge(x,y,c,k);
    }

    fout<<G.GetFlow(s, t);
    return 0;
}