Pagini recente » Sedinta 2008-10-21 | Cod sursa (job #238730)
Cod sursa(job #238730)
#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
}