Cod sursa(job #923945)

Utilizator FayedStratulat Alexandru Fayed Data 23 martie 2013 23:22:46
Problema Flux maxim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#define NMAX 1001
using namespace std;

vector < vector < int > >Graf;
int vizitat[NMAX];
int father[NMAX];
int Flow[NMAX][NMAX];
int Capacitate[NMAX][NMAX];
queue < int > q;
int n,m,flow,capacitate_reziduala;

inline void citesc(){

    int x,y,cap;
    freopen("maxflow.in","r",stdin);
    freopen("maxflow.out","w",stdout);
    scanf("%d%d",&n,&m);
    Graf.resize(n+1);
    for(register int i=1;i<=m;++i){
        scanf("%d%d%d",&x,&y,&cap);
        Capacitate[x][y] = cap;
        Graf[x].push_back(y);
        Graf[y].push_back(x); // construiesc graful rezidual
    }
}

int BFS(){  // Parcurg un drum de ameliorare

    memset(vizitat,0,sizeof(vizitat));
    vizitat[1] = 1;
    q.push(1);
    int nod,nod2;
    while(!q.empty()){

        nod = q.front();
        q.pop();
            for(register int i=0;i<Graf[nod].size();++i){
                nod2 = Graf[nod][i];
                if(Flow[nod][nod2]  == Capacitate[nod][nod2] || vizitat[nod2] == 1) // Daca nu mai pot mari fluxul sau deja a mai fost vizitat nodul curent continui cautarea
                    continue;
                vizitat[nod2] = 1;
                q.push(nod2);
                father[nod2] = nod;
    }
    }
return vizitat[n];
}

inline void Max_Flow(){

    while(BFS()) // atata timp cat am un drum de la sursa la destinatie

            for(register int i=0;i<Graf[n].size();++i){
                int nod2 = Graf[n][i];
                if(Capacitate[nod2][n] == Flow[nod2][n] || !vizitat[nod2])
                        continue;

            father[n] = nod2;
            capacitate_reziduala = 0x3f3f3f3f;
            for(register int i=n;i!=1;i=father[i])  // plec de la n deoarece n este o frunza a arborelui de tip father
                capacitate_reziduala = min(capacitate_reziduala,Capacitate[father[i]][i] - Flow[father[i]][i]); //daca mai creste fluxul ma asigur ca il voi creste cu

                if(!capacitate_reziduala) continue;                                                                                                //cea mai mica diferenta dintre cap si fluxul curent de pe un arc
                flow+=capacitate_reziduala;

            for(register int i=n;i!=1;i=father[i]){ // legea conservarii fluxului: cantitatea de flux ce intra intr-un nod este egala cu cant de flux ce iese din nod
                Flow[father[i]][i]+=capacitate_reziduala; // scad cap reziduala de la i la father[i] in caz ca eu am arc de la i la father[i]
                Flow[i][father[i]]-=capacitate_reziduala;
            }
        }

printf("%d",flow);
}

int main(){

    citesc();
    Max_Flow();
return 0;
}