Cod sursa(job #2156056)

Utilizator horiainfoTurcuman Horia horiainfo Data 8 martie 2018 13:59:21
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>

#define N 400
using namespace std;

typedef pair<int, int> pii;
struct Edge{int next, flow, cost;};

bool inQ[N];
int dist[N], in[N], S, T, minCost[N], realCost[N];
queue<int> q;
priority_queue<pii, vector<pii>, greater<pii>> q2;
vector<Edge> E;
vector<int> G[N];

void MinDist(){

    memset(dist, 0x3f, sizeof(dist));
    q.push(S); inQ[S] = 1; dist[S] = 0;

    while(!q.empty()){
        int node = q.front(); q.pop();
        inQ[node] = 0;

        for(auto e : G[node])
            if(E[e].flow){
                int next = E[e].next,
                    newDist = dist[node] + E[e].cost;

                if(dist[next] <= newDist) continue;
                dist[next] = newDist;
                if(!inQ[next])  q.push(next), inQ[next] = 0;
            }
    }
}

bool Dijkstra(){
    memset(minCost, 0x3f, sizeof(minCost));
    q2.push({0, S}); minCost[S] = 0;

    while(!q2.empty()){
        int node = q2.top().second;
        int cost = q2.top().first; q2.pop();
        if(cost != minCost[node]) continue;

        for(auto e : G[node])
            if(E[e].flow){
                int next = E[e].next;
                int c = cost + E[e].cost + dist[node] - dist[next];
                if(c >= minCost[next]) continue;
                minCost[next] = c; q2.push({c, next});
                realCost[next] = realCost[node] + E[e].cost;
                in[next] = e ^ 1;
            }
    }

    memcpy(dist, realCost, sizeof(dist));
    return minCost[T] != 0x3f3f3f3f;
}

int main(){
    int n, m; freopen("fmcm.in", "r", stdin);
    cin >> n >> m >> S >> T;
    while(m --){
        int x, y, c, z; cin >> x >> y >> c >> z;

        G[x].push_back(E.size());
        E.push_back({y, c, z});
        
        G[y].push_back(E.size());
        E.push_back({x, 0, -z});
    }

    int cost = 0; in[S] = -1;
    MinDist(); while(Dijkstra()){

        int f = 0x3f3f3f3f;
        for(int e = in[T]; e != -1; e = in[E[e].next])
            f = min(f, E[e ^ 1].flow);
        
        for(int e = in[T]; e != -1; e = in[E[e].next])
            E[e].flow += f, E[e ^ 1].flow -= f;

        cost += f * dist[T];
    }
    freopen("fmcm.out", "w", stdout); cout << cost;
}