Pagini recente » Cod sursa (job #1336794) | Cod sursa (job #1549802) | Cod sursa (job #574137) | Cod sursa (job #2012755) | Cod sursa (job #147547)
Cod sursa(job #147547)
#include<stdio.h>
void citire();
void flux();
void conex1();
void conex2();
void afisare();
long path();
long n,m,grad[1001],x[10001],y[10001],
cp[1001][1001],fl[1001][1001],*vec[1001],dad[1001],coada[1001];
int main()
{
citire();
flux();//algoritmul lui Dinic
conex1();//noduri conectate la sursa in reteaua reziduala
conex2();//noduri conectate la destinatie in reteaua reziduala
afisare();
return 0;
}
void citire()
{ long i,xx,yy,cc;
FILE *f=fopen("critice.in","r");
fscanf(f,"%ld%ld",&n,&m);//n=nr varfuri;m=nr muchii;
for(i=1;i<=m;i++)
{ fscanf(f,"%ld%ld%ld",&xx,&yy,&cc);
grad[xx]++;grad[yy]++;x[i]=xx;y[i]=yy;
cp[xx][yy]=cp[yy][xx]=cc;
}//citire muchii si capacitati;calcul grade varfuri;
for(i=1;i<=n;i++)
{ vec[i]=new long [grad[i]+2];
vec[i][grad[i]+1]=0;
grad[i]=0;
}//alocare spatiu pt lista vecini;
for(i=1;i<=m;i++)
{ vec[x[i]][++grad[x[i]]]=y[i];
vec[y[i]][++grad[y[i]]]=x[i];
}//creare lista vecini
fclose(f);
}
void flux()
{ long 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
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;
}
}
}
}
long path()
//cauta drum minim sursa->destinatie in reteaua reziduala prin BFS
{
long 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
}
void conex1()
{ long i,first,last,ii,jj,nv;
for(i=1;i<=n;i++)dad[i]=0;dad[1]=1;
first=1;last=1;coada[1]=1;
while(first<=last)
{ ii=coada[first];
nv=grad[ii];
for(i=1;i<=nv;i++)
{ jj=vec[ii][i];
if(dad[jj])continue;
if(cp[ii][jj]<=fl[ii][jj])continue;
coada[++last]=jj;
dad[jj]=1;
}
first++;
}
}
void conex2()
{ long i,first,last,ii,jj,nv;
dad[n]=2;
first=1;last=1;coada[1]=n;
while(first<=last)
{ ii=coada[first];
nv=grad[ii];
for(i=1;i<=nv;i++)
{ jj=vec[ii][i];
if(dad[jj])continue;
if(cp[jj][ii]<=fl[jj][ii])continue;
coada[++last]=jj;
dad[jj]=2;
}
first++;
}
}
void afisare()
{ long i,sol=0;
FILE *f=fopen("critice.out","w");
for(i=1;i<=m;i++)
if(dad[x[i]]+dad[y[i]]==3)sol++;
fprintf(f,"%ld\n",sol);
for(i=1;i<=m;i++)
if(dad[x[i]]+dad[y[i]]==3)
fprintf(f,"%ld\n",i);
fclose(f);
}