Cod sursa(job #2659353)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 16 octombrie 2020 17:16:38
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.85 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

int N, source, sink, min_cost;
vector < vector < int > > Graph, Capacity, Cost;
vector < int > parent, old_d, real_d, D;

const int INF = 2e9;

inline void min_self(int& a, int b) {
    a = min(a, b);
}

void BellmanFord() {
    old_d.assign(N + 1, INF);
    old_d[source] = 0;
    queue < int > Q;
    Q.emplace(source);
    vector < bool > inQ(N + 1);
    inQ[source] = true;
    while(!Q.empty()) {
        int curr = Q.front();
        Q.pop();
        inQ[curr] = false;
        for(int next : Graph[curr])
            if(Capacity[curr][next] && old_d[curr] + Cost[curr][next] < old_d[next]) {
                old_d[next] = old_d[curr] + Cost[curr][next];
                if(!inQ[next]) {
                    Q.emplace(next);
                    inQ[next] = true;
                }
            }
    }
}

bool Dijkstra() {
    priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > Q;
    D.assign(N + 1, INF);
    D[source] = real_d[source] = 0;
    Q.emplace(0, source);
    while(!Q.empty()) {
        int cost = Q.top().first,
            curr = Q.top().second;
        Q.pop();
        if(D[curr] != cost)
            continue;
        for(int next : Graph[curr])
            if(Capacity[curr][next]) {
                int new_d = D[curr] + Cost[curr][next] + old_d[curr] - old_d[next];
                if(new_d < D[next]) {
                    D[next] = new_d;
                    real_d[next] = real_d[curr] + Cost[curr][next];
                    parent[next] = curr;
                    Q.emplace(D[next], next);
                }
            }
    }
    if(D[sink] == INF)
        return false;
    int new_flow = INF;
    for(int node = sink; node != source; node = parent[node])
        min_self(new_flow, Capacity[parent[node]][node]);
    if(new_flow == 0)
        return true;
    min_cost += new_flow * real_d[sink];
    for(int node = sink; node != source; node = parent[node]) {
        Capacity[parent[node]][node] -= new_flow;
        Capacity[node][parent[node]] += new_flow;
    }
    return true;
}

int main() {
    fin.sync_with_stdio(false);
    fout.sync_with_stdio(false);
    fin.tie(nullptr);
    fout.tie(nullptr);
    int M;
    fin >> N >> M >> source >> sink;
    Graph.resize(N + 1);
    parent.resize(N + 1);
    real_d.resize(N + 1);
    Capacity = Cost = vector < vector < int > >(N + 1, vector < int >(N + 1));
    while(M--) {
        int u, v, capacity, w;
        fin >> u >> v >> capacity >> w;
        Graph[u].emplace_back(v);
        Graph[v].emplace_back(u);
        Capacity[u][v] = capacity;
        Cost[u][v] = w;
        Cost[v][u] = -w;
    }
    BellmanFord();
    while(Dijkstra());
    fout << min_cost;
}