Cod sursa(job #1224196)

Utilizator mihai995mihai995 mihai995 Data 30 august 2014 00:56:55
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.67 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

const int N = 351, QSize = (1 << 9) - 1, inf = 0x3f3f3f3f;

class Queue{
    int v[QSize + 1], st, dr;
    bool use[N];

public:
    Queue(){
        st = dr = 0;
    }

    inline void push(int x){
        if (!use[x]){
            v[dr++] = x;
            use[x] = true;
            dr &= QSize;
        }
    }

    inline int pop(){
        int x = v[st++];
        use[x] = false;
        st &= QSize;
        return x;
    }

    inline bool isEmpty(){
        return st == dr;
    }
};

struct Edge{
    int y, c;

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

int cf[N][N], dist[N], T[N], n;
vector<Edge> graph[N];
bool use[N];
Queue Q;

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

bool bellmanFord(int x, int D){
    memset(dist, inf, sizeof(dist));
    dist[x] = 0;
    Q.push(x);

    while ( !Q.isEmpty() ){
        x = Q.pop();

        for (Edge E : graph[x])
            if ( cf[x][E.y] && dist[x] + E.c < dist[E.y]){
                dist[E.y] = dist[x] + E.c;
                Q.push(E.y);
                T[E.y] = x;
            }
    }

    return dist[D] != inf;
}

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

    do{
        use[x] = true;
        for (Edge E : graph[x])
            if (cf[x][E.y] && dist[x] + E.c < dist[E.y]){
                dist[E.y] = dist[x] + E.c;
                T[E.y] = x;
            }

        x = 0;
        for (int i = 1 ; i <= n ; i++)
            if ( !use[i] && dist[i] < dist[x] )
                x = i;
    } while (x);

    return dist[D] != inf;
}

int rebuildGraph(int S, int D){
    bellmanFord(S, D);

    for (int x = 1 ; x <= n ; x++)
        for (auto it = graph[x].begin() ; it != graph[x].end() ; it++)
            it -> c += dist[x] - dist[it -> y];
    return dist[D];
}

int maxFlow(int S, int D){
    int flow = 0, cost = 0, delta = rebuildGraph(S, D);
    while ( dijkstra(S, D) ){
        int F = inf;
        for (int i = D ; i != S ; i = T[i])
            F = min(F, cf[ T[i] ][i]);
        for (int i = D ; i != S ; i = T[i])
            relax(T[i], i, F);

        cost += F * (delta + dist[D]);
        flow += F;
    }
    return cost;
}

int main(){
    ifstream in("fmcm.in");
    int m, x, y, cap, cost, S, D;

    in >> n >> m >> S >> D;
    while (m--){
        in >> x >> y >> cap >> cost;

        cf[x][y] = cap;
        graph[x].push_back( Edge(y, cost) );
        graph[y].push_back( Edge(x, -cost) );
    }

    in.close();

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

    return 0;
}