Cod sursa(job #1464994)

Utilizator TeodorescuStefanEduardTeodorescu Stefan Eduard TeodorescuStefanEduard Data 26 iulie 2015 11:40:14
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.74 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define MAX 355
#define INF 1<<30
#define mp make_pair
#define pair pair<int,int>
#define min(a, b) (a < b ? a : b)
using namespace std;
 
int n, m, i, x, y, c, z, G[MAX][MAX], C[MAX][MAX], cost[MAX][MAX];
int source, dest, minim, flow, parent[MAX];
int DB[MAX], DD[MAX], DR[MAX];
vector<int> l[MAX];
queue<int> q;
bool viz[MAX];
 
priority_queue< pair, vector<pair>, greater<pair> > pq;
 
void BellmanFord(int s);
bool Dijkstra(int s);
 
int main(){
    freopen("fmcm.in", "r", stdin);
    freopen("fmcm.out", "w", stdout);
    scanf("%d%d%d%d", &n, &m, &source, &dest);
    for(i = 0; i < m; i++){
        scanf("%d%d%d%d", &x, &y, &c, &z);
        C[x][y] = c;
        cost[x][y] = z;
        l[x].push_back(y);
        cost[y][x] = -z;
        l[y].push_back(x);
    }
 
    BellmanFord(source);
 
    while(Dijkstra(source)){
        minim = INF;
        int v = dest;
        while(v != parent[v]){
            int u = parent[v];
            minim = min(minim, C[u][v] - G[u][v]);
            v = u;
        }
        v = dest;
        while(v != parent[v]){
            int u = parent[v];
            G[u][v] += minim;
            G[v][u] -= minim;
            v = u;
        }
        flow += minim * DB[dest];
    }
 
    printf("%d", flow);
    return 0;
}
 
void BellmanFord(int s){
    memset(DB, INF, n + 1);
    DB[s] = 0;
    viz[s] = true;
     
    for(q.push(s); !q.empty(); q.pop()){
        i = q.front();
        viz[i] = false;
        for(vector<int>::iterator it = l[i].begin(); it < l[i].end(); it++){
            if(DB[*it] > DB[i] + cost[i][*it] && G[i][*it] < C[i][*it]){
                DB[*it] = DB[i] + cost[i][*it];
                if(!viz[*it]){
                    viz[*it] = true;
                    q.push(*it);
                }
            }
        }
    }
}
 
bool Dijkstra(int s){
    for(i = 1; i <= n; i++)
        DD[i] = INF;
    DD[s] = 0;
    pq.push(mp(0, s));
    parent[s] = s;
 
    while(!pq.empty()){
        int aux = pq.top().second;
        int costaux = pq.top().first;
        pq.pop();
 
        if(costaux > DD[aux])
            continue;
 
        for(vector<int>::iterator it = l[aux].begin(); it < l[aux].end(); it++)
            if(G[aux][*it] < C[aux][*it])
                if(DD[aux] + cost[aux][*it] + DB[aux] - DB[*it] < DD[*it]){
                    DD[*it] = DD[aux] + cost[aux][*it] + DB[aux] - DB[*it];
                    DR[*it] = DR[aux] + cost[aux][*it];
                    parent[*it] = aux;
                    pq.push(mp(DD[*it], *it));
                }
    }
 
    for(i = 1; i <= n; i++)
        DB[i] = DR[i];
    return DD[dest] != INF;
}