Cod sursa(job #1194658)

Utilizator mihai995mihai995 mihai995 Data 4 iunie 2014 15:21:57
Problema Flux maxim de cost minim Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.67 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;

const int N = 351, inf = 0x3f3f3f3f;

struct Edge{
    int y, c;

    Edge(int y, int c) : y(y), c(c) {};

    inline bool operator<(const Edge& E) const {
        return c > E.c;
    }
};

vector<Edge> graph[N];
int cap[N][N], flux[N][N], cost[N][N], n;
int dist[N], T[N];
bool use[N];

inline int getCap(int x, int y){
    return cap[x][y] - flux[x][y];
}

inline void relax(int x, int y, int c){
    flux[x][y] += c;
    flux[y][x] -= c;
}

void bellmanFord(int x){
    memset(dist, inf, sizeof(dist));;
    memset(use, false, sizeof(use));
    dist[x] = 0;

    queue<int> Q;

    Q.push(x);
    while (!Q.empty()){
        x = Q.front();
        Q.pop();
        use[x] = false;

        for (Edge it : graph[x]){
            int i = it.y;
            if ( dist[x] + cost[x][i] < dist[i] && getCap(x, i) > 0){
                dist[i] = dist[x] + cost[x][i];
                T[i] = x;
                if (!use[i]){
                    Q.push(i);
                    use[i] = true;
                }
            }
        }
    }
}

bool dijkstra(int x, int D){
    memset(dist, inf, sizeof(dist));
    memset(use, false, sizeof(use));
    dist[x] = 0;

    priority_queue<Edge> Q;
    Q.push( Edge(x, 0) );

    while (!Q.empty()){
        x = Q.top().y;
        Q.pop();

        if (use[x])
            continue;
        use[x] = true;

        for (Edge it : graph[x])
            if ( dist[x] + it.c < dist[it.y] && getCap(x, it.y) > 0 ){
                T[it.y] = x;
                dist[it.y] = dist[x] + it.c;
                Q.push( Edge(it.y, dist[it.y]) );
            }
    }

    return use[D];
}

void rebuildGraph(int S){
    bellmanFord(S);
    for (int i = 1 ; i <= n ; i++)
        for (auto it = graph[i].begin() ; it != graph[i].end() ; it++)
            it -> c += dist[i] - dist[it -> y];
}

int maxFlow(int S, int D){
    int totCost = 0, C, F;

    rebuildGraph(S);
    while ( dijkstra(S, D) ){
        F = inf;
        C = 0;
        for (int i = D ; i != S ; i = T[i]){
            F = min(F, getCap(T[i], i));
            C += cost[ T[i] ][i];
        }
        for (int i = D ; i != S ; i = T[i])
            relax(T[i], i, F);
        totCost += C * F;
    }

    return totCost;
}

int main(){
    int m, x, y, S, D;

    ifstream in("fmcm.in");
    in >> n >> m >> S >> D;
    while (m--){
        in >> x >> y;
        in >> cap[x][y] >> cost[x][y];
        cost[y][x] = -cost[x][y];

        graph[x].push_back( Edge(y, cost[x][y]) );
        graph[y].push_back( Edge(x, cost[y][x]) );
    }
    in.close();

    ofstream out("fmcm.out");
    out << maxFlow(S, D) << '\n';
    out.close();

    return 0;
}