Cod sursa(job #932941)

Utilizator vendettaSalajan Razvan vendetta Data 29 martie 2013 13:46:58
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.73 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

ifstream f("fmcm.in");
ofstream g("fmcm.out");

#define nmax 356
#define Mmax 12500
#define ll long long
#define inf (1<<30)

int n, m, S, D, capac[nmax][nmax], flux[nmax][nmax];
vector< pair<int,int> > gf[nmax];
int dist[nmax], t[nmax];
bool viz[nmax];
int q[nmax*Mmax];// in total pot fi namx noduri in coada la un moment de timp; dar asta nu insemana ca un nod nu va fi de mai multe ori in coada
//=> un nod poate fi de maxim n * m ori

void citeste(){
    f >> n >> m >> S >> D;
    int x, y, c, z;
    for(int i=1; i<=m; ++i){
        f >> x >> y >> c >> z;
        gf[x].push_back( make_pair(y, z) );
        gf[y].push_back( make_pair(x, -z) );// ii dau negatie pt ca pe asta o sa il intorc ( adica nu o sa bag pe ea si trebuie scos costul)
        capac[x][y] = c;
    }
}

inline int Bf(){
    for(int i=0; i<=n; ++i) viz[i] = 0, t[i] = 0, dist[i] = inf;
    int st = 1; int dr = 1;
    q[dr] = S; // bag sursa
    viz[S] = 1;// e in coada;
    dist[S] = 0;

    for(; st<=dr; ){
        int nod = q[st]; ++st;
        viz[nod] = 0;//l-am scos din coada
        for(int i=0; i<gf[nod].size(); ++i){
            int vc = gf[nod][i].first;
            int cost = gf[nod][i].second;
            // vreau sa bag flux pe muchia nod->vc
            if ( capac[nod][vc] > flux[nod][vc] && dist[vc] > dist[nod] + cost ){//daca mai pot baga flux pe muchia asta
                // iar daca pot imbuntati costul de la Sursa la vc; o fac
                dist[vc] = dist[nod] + cost;
                t[vc] = nod;
                if (viz[vc] == 0){
                    viz[vc] = 1;// l-am bagat in coada
                    q[++dr] = vc;
                }
            }
        }
    }
    return dist[D];
}

void rezolva(){
    int CostMin = 0;
    for(int ok=1; ok; ){
        // aleg muhia minima
        int Cost = Bf();
        if (Cost == inf) break;// daca nu am ajuns in destinatie
        int Min = inf;
        for(int i=D; i!=S; i=t[i]){
            // am bagat pe t[i] -> i
            Min = min(Min, capac[ t[i] ][i] - flux[ t[i] ][i] );
        }
        //acum bag fluxul
        for(int i=D; i!=S; i=t[i]){
            // am bagat pe t[i] -> i
            flux[ t[i] ][i] = flux[ t[i] ][i] + Min;
            flux[i][ t[i] ] -= Min;// il intorc
        }
        CostMin += (Cost*Min);// adaug costul pentru a baga fluxul curent// pt fiecare unitate de flux transmisa ma costa Cost bani
    }
    cout << CostMin << "\n";
    g << CostMin << "\n";
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}