Cod sursa(job #2117240)

Utilizator LucaSeriSeritan Luca LucaSeri Data 28 ianuarie 2018 18:24:39
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.93 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 355;
const int INF = (1<<30);

int capacity[MAXN][MAXN];
int current_flow[MAXN][MAXN];
int dist[MAXN];
int old[MAXN];
int viz[MAXN];
int real_d[MAXN];
vector< pair<int, int> > gr[MAXN];
int boss[MAXN];

ifstream f("fmcm.in");
ofstream g("fmcm.out");

class cmp{
public:
    const bool operator()(const pair<int, int> &a, const pair<int, int> & b) const{
            return a.second > b.second;
    }
};

priority_queue< pair<int, int>, vector< pair<int, int> >, cmp > H;

bool dijkstra(int source, int target, int n){

    memset(dist, 0x3f, sizeof dist);
    memset(boss, 0, sizeof boss);
    dist[source] = 0;
    real_d[source] = 0;
    H.push({source, 0});
    while(H.size()){
        int node = H.top().first;
        int cost = H.top().second;
        H.pop();
        if(cost != dist[node]) continue;

        for(auto x : gr[node]){
            int c = cost + x.second  + old[node] - old[x.first];

            if(c < dist[x.first] && current_flow[node][x.first] < capacity[node][x.first]){
                dist[x.first] = c;
                real_d[x.first] = real_d[node] + x.second;
                boss[x.first] = node;
                H.push({x.first, dist[x.first]});
            }
        }
    }

    memcpy(old, real_d, sizeof old);

    return dist[target] != 0x3f3f3f3f;
}

void bf(int source, int target, int n){
    memset(old, 0x3f, sizeof old);
    memset(viz, 0, sizeof viz);
    old[source] = 0;

    queue< int > Q;

    Q.push(source);
    viz[source] = true;
    while(Q.size()){
        int node = Q.front();
        viz[node] = false;
        Q.pop();
        for(auto x : gr[node]){
            if(capacity[node][x.first] > current_flow[node][x.first] && dist[x.first] > dist[node] + x.second){
                old[x.first] = old[node] + x.second;
                if(viz[x.first]) continue;

                viz[x.first] = true;
                Q.push(x.first);
            }
        }
    }
}
int main(){
    int n, m, source, target;
    f >> n >> m >> source >> target;

    while(m--){
        int a, b, c, d;
        f >> a >> b >> c >> d;
        gr[a].push_back({b, d});
        gr[b].push_back({a, -d});
        capacity[a][b] += c;
    }

    bf(source, target, n);
    int ans = 0;
    while(dijkstra(source, target, n)){
        int node = target;
        int minimum_flow = INF;

        while(node != source){
            minimum_flow = min(minimum_flow, capacity[ boss[node] ][node] - current_flow[ boss[node] ][node]);
            node = boss[node];

        }

        node = target;
        while(node != source){
            current_flow[ boss[node] ][node] += minimum_flow;
            current_flow[node][ boss[node] ] -= minimum_flow;
            node = boss[node];
        }

        ans += (real_d[target] * minimum_flow);
    }

    g << ans;
    return 0;
}