Cod sursa(job #926238)

Utilizator apopeid13Apopeid Alejandro apopeid13 Data 25 martie 2013 08:30:46
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 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();
            if(nod == n) continue;
            for(vector < int >::iterator it = Graf[nod].begin();it!=Graf[nod].end();++it)
                if(Flow[nod][*it]  < Capacitate[nod][*it] && !vizitat[*it]){ // Daca nu mai pot mari fluxul sau deja a mai fost vizitat nodul curent continui cautarea
                vizitat[*it] = 1;
                q.push(*it);
                father[*it] = nod;
                }
    }
return vizitat[n];
}
 
inline void Max_Flow(){
 
    while(BFS()){  // atata timp cat am un drum de la sursa la destinatie
 
            for(vector < int >::iterator it = Graf[n].begin();it!=Graf[n].end();++it){
                if(Capacitate[*it][n] == Flow[*it][n] || !vizitat[*it])
                        continue;
 
            father[n] = *it;
            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;
}