Cod sursa(job #714998)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 16 martie 2012 14:03:07
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include<stdio.h>
#include<assert.h>

#include<vector>
#include<queue>
#include<algorithm>

using namespace std;

const int knmax = 1023, ko9k = 900000001;
int verts, edges, source, dest, dad[knmax], vis[knmax], cap[knmax][knmax], cost[knmax][knmax], f[knmax][knmax];
int sol;

void read(){
    assert(freopen("fmcm.in","r",stdin) != NULL);
    int i, aux_x, aux_y, aux_cap, aux_cost;
    scanf("%d%d%d%d", &verts, &edges, &source, &dest);
    for(i = 1; i <= edges; ++i){
        scanf("%d%d%d%d", &aux_x, &aux_y, &aux_cap, &aux_cost);
        cap[aux_x][aux_y] = aux_cap;
        cost[aux_x][aux_y] = aux_cost;
        cost[aux_y][aux_x] = -aux_cost;
    }
}

void init(){
    for(int i = 1; i <= verts; ++i)
        vis[i] = ko9k;
    vis[source] = 0;
}

int blm(){
    init();

    int i, now;
    queue<int> q;
    q.push(source);

    while(!q.empty()){
        now = q.front();
        q.pop();

        for(i = 1; i <= verts; ++i)
            if(cap[now][i] > f[now][i] && vis[i] > vis[now] + cost[now][i]){
                q.push(i);
                vis[i] = vis[now] + cost[now][i];
                dad[i] = now;
            }
    }
    if(vis[dest] < ko9k)
        return 1;
    return 0;
}

void solve(){
    int i, c_flow;
    while(blm()){
        c_flow = ko9k;

        for(i = dest; i != source; i = dad[i])
            c_flow = min(c_flow, cap[dad[i]][i] - f[dad[i]][i]);

        for(i = dest; i != source; i = dad[i]){
            sol += c_flow * cost[dad[i]][i];
            f[dad[i]][i] += c_flow;
            f[i][dad[i]] -= c_flow;
        }
    }
}

void write(){
    assert(freopen("fmcm.out","w",stdout) != NULL);
    printf("%d",sol);
}

int main(){
    read();
    solve();
    write();
    return 0;
}