Cod sursa(job #400590)
Utilizator | Data | 21 februarie 2010 17:45:42 | |
---|---|---|---|
Problema | Flux maxim de cost minim | Scor | 0 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 4.49 kb |
using namespace std;
#include<fstream>
#define INFINIT 2147483647
int c[355][355],z1[355][355],z2[355][355],d[355],v[355],t[355],h[355],poz[355],nH,N,M,S,D,cost;
struct coada
{
int info;
coada* next;
};
int dijkstra();
void cerne(int);
void promoveaza(int);
int main()
{
coada *st,*dr,*q;
int i,x,y,cc,z,cmin;
ifstream fin("fmcm.in");
fin>>N>>M>>S>>D;
for(i=1;i<=M;++i)
{
fin>>x>>y>>cc>>z;
c[x][y]=cc;
z1[x][y]=z;
z1[y][x]=-z;
}
for(i=1;i<=N;++i)
d[i]=INFINIT;
st=new coada;
dr=st;
st->info=S;
st->next=NULL;
v[S]=1;
d[S]=0;
while(st)
{
x=st->info;
v[x]=0;
if(d[x]<INFINIT)
for(i=1;i<=N;++i)
if(c[x][i])
if(d[i]>d[x]+z1[x][i])
{
d[i]=d[x]+z1[x][i];
if(v[i]==0)
{
q=new coada;
dr->next=q;
dr=dr->next;
dr->info=i;
dr->next=NULL;
v[i]=1;
}
}
q=st;
st=st->next;
delete q;
}
for(x=1;x<=N;++x)
for(i=1;i<=N;++i)
if(c[x][i])
z2[x][i]=z1[x][i]+d[x]-d[i];
while(dijkstra())
{
cmin=INFINIT;
for(x=N;t[x];x=t[x])
if(c[t[x]][x]<cmin)
cmin=c[t[x]][x];
for(x=N;t[x];x=t[x])
{
c[t[x]][x]-=cmin;
c[x][t[x]]+=cmin;
cost+=z1[t[x]][x]*cmin;
}
}
ofstream fout("fmcm.out");
fout<<cost;
return 0;
}
int dijkstra()
{
int i,x,pmin;
for(i=0;i<=N;++i)
{
d[i]=INFINIT;
t[i]=-1;
v[i]=0;
h[i]=i;
poz[i]=i;
}
nH=N;
v[S]=1;
d[S]=t[S]=0;
h[S]=h[nH--];
poz[h[S]]=S;
cerne(S);
for(i=1;i<=N;++i)
if(c[S][i])
{
d[i]=z2[S][i];
t[i]=S;
promoveaza(poz[i]);
}
for(x=1;x<N;++x)
{
pmin=h[1];
if(d[pmin]==INFINIT)
break;
v[pmin]=1;
h[1]=h[nH--];
poz[h[1]]=1;
cerne(1);
for(i=1;i<=N;++i)
if(c[pmin][i])
if(v[i]==0)
if(d[i]>d[pmin]+z2[pmin][i])
{
d[i]=d[pmin]+z2[pmin][i];
t[i]=pmin;
promoveaza(poz[i]);
}
}
if(d[D]<INFINIT)
return 1;
return 0;
}
void cerne(int k)
{
int eh=0,i,aux;
while(eh==0 && 2*k<=nH)
{
i=2*k;
if(i+1<=N)
if(d[h[i]]>d[h[i+1]])
++i;
if(d[h[k]]<=d[h[i]])
eh=1;
else
{
aux=h[i];
h[i]=h[k];
h[k]=aux;
poz[h[i]]=i;
poz[h[k]]=k;
k=i;
}
}
}
void promoveaza(int k)
{
int eh=0,i,aux;
while(eh==0 && k/2)
{
i=k/2;
if(d[h[i]]<=d[h[k]])
eh=1;
else
{
aux=h[i];
h[i]=h[k];
h[k]=aux;
poz[h[i]]=i;
poz[h[k]]=k;
k=i;
}
}
}