Cod sursa(job #238730)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 3 ianuarie 2009 01:13:38
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.04 kb
#include<stdio.h>   
#define N
void readd(),flux(),afisare();
int path();   
int n,m,grad[1001],cp[1001][1001],fl[1001][1001],*vec[1001],dad[1001],
coada[1001],flux_sol;   
int main()   
{   
    readd();   
    flux();//algoritmul lui Dinic   
    return 0;   
}   
void readd()   
{   int i,xx,yy,cc;   
    freopen("maxflow.in","r",stdin);
    freopen("maxflow.out","w",stdout);   
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)   
    { scanf("%d%d%d",&xx,&yy,&cc);   
      grad[xx]++;grad[yy]++;   
    }//citire muchii si capacitati;calcul grade varfuri;   
    for(i=1;i<=n;i++)   
    { vec[i]=new int [grad[i]+2];   
      vec[i][grad[i]+2]=0;   
      grad[i]=0;   
    }//alocare spatiu pt lista vecini;   
    freopen("maxflow.in","r",stdin);   
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)   
    { scanf("%d%d%d",&xx,&yy,&cc);
      vec[xx][++grad[xx]]=yy;
      vec[yy][++grad[yy]]=xx;
      cp[xx][yy]=cc;   
    }//creare lista vecini   
}   
void flux()   
{   int i,fl_drum,j;   
    while(path())   
    {  for(i=1;i<=n;i++)   
       { if(!dad[i])continue;   
         if(cp[i][n]<=fl[i][n])continue;   
         //se alege un nod numai daca exista un drum minim   
         //sursa->....->nod->destinatie   
         //deci drum de lungime minima. astfel la o aplicare   
         //a unui pas se vor satura toate drumurile minime   
         fl_drum=cp[i][n]-fl[i][n];   
         for(j=i;j!=1;j=dad[j])   
          if(fl_drum>cp[dad[j]][j]-fl[dad[j]][j])   
           fl_drum=cp[dad[j]][j]-fl[dad[j]][j];   
         //calculeaza fluxul pe drumul minim ales   
         if(!fl_drum)continue;   
         //drumul a fost deja saturat-sari peste   
         //altfel se satureaza drumul respectiv   
         flux_sol+=fl_drum;
         fl[i][n]+=fl_drum;fl[n][i]-=fl_drum;   
         for(j=i;j!=1;j=dad[j])   
         { fl[dad[j]][j]+=fl_drum;   
           fl[j][dad[j]]-=fl_drum;   
         }   
       }   
    }
    printf("%d\n",flux_sol);   
}   
int path()   
//cauta drum minim sursa->destinatie in reteaua reziduala prin BFS   
{   
    int i,ii,jj,nv,first,last;   
    for(i=2;i<=n;i++) dad[i]=0;dad[1]=-1;   
    //reinitializare vector de predecesori   
    first=last=1;coada[first]=1;   
    //initializare coada cu sursa=1   
    while(first<=last)   
    { ii=coada[first];//nod curent = primul nod din coada   
      nv=grad[ii];   
      for(i=1;i<=nv;i++)   
      { jj=vec[ii][i];   
        if(dad[jj])continue;   
        //daca vecin intrat in coada sari peste   
        if(cp[ii][jj]<=fl[ii][jj])continue;   
        //daca vecin fals in reteaua reziduala sari peste   
        dad[jj]=ii;   
        //predecesor vecin = nod curent   
        last++;coada[last]=jj;   
        //vecin intra in coada   
        if(jj==n)return 1;   
        // daca destinatia a intrat in coada am gasit drumul   
      }//parcurgere vecini nod curent   
      first++;   
    }//parcurgerea in latime (BFS)   
    return 0;//daca destinatia nu a fost atinsa nu exista drum   
}