Cod sursa(job #721247)

Utilizator ioalexno1Alexandru Bunget ioalexno1 Data 23 martie 2012 14:50:44
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include <cstdio>
#define N 405
#define inf 1999999999
using namespace std;
struct nod{ int val; nod *urm; }*G[N];
int cost[N][N],cap[N][N],dist[N],flux[N][N];
int heap[N],lgheap,poz[N],tata[N];
int n,m,S,D,sum,sol;
bool viz[N],drum;
void read()
{ int i,x,y,z,t;
  nod *aux;
freopen("fmcm.in","r",stdin); scanf("%d %d %d %d\n",&n,&m,&S,&D);
for(i=1;i<=m;++i)
    {
    scanf("%d %d %d %d\n",&x,&y,&z,&t);
    aux=new nod; aux->val=y; aux->urm=G[x]; G[x]=aux;
    aux=new nod; aux->val=x; aux->urm=G[y]; G[y]=aux;
    cost[x][y]=t; cost[y][x]=-t; cap[x][y]=z;
    }
fclose(stdin);
}
void bellman_ford()
{ int i,j,stop=0;
  nod *aux;
for(i=1;i<=n;++i)dist[i]=inf;
dist[S]=0;
for(i=1;i<=n&&!stop;++i)
    {
    stop=1;
    for(j=1;j<=n;++j)
        for(aux=G[j];aux!=NULL;aux=aux->urm)
            if(cap[j][aux->val]>flux[j][aux->val]&&dist[j]+cost[j][aux->val]<dist[aux->val])
                {
                stop=0;
                dist[aux->val]=dist[j]+cost[j][aux->val];
                }
    }
sum=dist[D];
}
void extractmin()
{ int tata,fiu,z;
  bool e;
poz[heap[1]]=-1; poz[heap[lgheap]]=1;
heap[1]=heap[lgheap]; heap[lgheap]=0; --lgheap;
tata=1; fiu=2; e=true;
while(e&&fiu<=lgheap)
    {
    e=false;
    if(dist[heap[fiu+1]]<dist[heap[fiu]]&&fiu+1<=lgheap)++fiu;
    if(dist[heap[tata]]>dist[heap[fiu]])
        {
        e=true;
        z=poz[heap[tata]]; poz[heap[tata]]=poz[heap[fiu]]; poz[heap[fiu]]=z;
        z=heap[tata]; heap[tata]=heap[fiu]; heap[fiu]=z;
        tata=fiu; fiu=tata<<1;
        }
    }
}
void upinheap(int ind)
{ int fiu,tata,z;
  bool e;
fiu=poz[ind];
tata=fiu>>1; e=true;
while(tata>=1&&e)
    {
    e=false;
    if(dist[heap[tata]]>dist[heap[fiu]])
                        {
                        e=true;
                        z=poz[heap[tata]]; poz[heap[tata]]=poz[heap[fiu]]; poz[heap[fiu]]=z;
                        z=heap[tata]; heap[tata]=heap[fiu]; heap[fiu]=z;
                        fiu=tata; tata=fiu>>1;
                        }
    }
}
inline int min(int x,int y)
{
if(x<y)return x; else return y; return 0;
}
int dijkstra()
{ int i,x,y,fm;
  nod *aux;
for(i=1;i<=n;++i)
    for(aux=G[i];aux!=NULL;aux=aux->urm)
        if(dist[i]!=inf&&dist[aux->val]!=inf)cost[i][aux->val]+=dist[i]-dist[aux->val];
for(i=1;i<=n;++i)
    {
    dist[i]=inf; heap[i]=i; poz[i]=i; tata[i]=-1;
    }
dist[S]=0; lgheap=n;
heap[1]=S; heap[S]=1;
poz[1]=S; poz[S]=1;
while(lgheap>=1)
    {
    x=heap[1]; extractmin();
    for(aux=G[x];aux!=NULL;aux=aux->urm)
        {
        y=aux->val;
        if(dist[y]>dist[x]+cost[x][y]&&cap[x][y]>flux[x][y])
                {
                dist[y]=dist[x]+cost[x][y];
                tata[y]=x;
                upinheap(y);
                }
            }
    }
if(dist[D]!=inf)
    {
    fm=inf; drum=1;
    for(i=D;i!=S;i=tata[i])
        fm=min(fm,cap[tata[i]][i]-flux[tata[i]][i]);
    for(i=D;i!=S;i=tata[i])
        {
        flux[tata[i]][i]+=fm;
        flux[i][tata[i]]-=fm;
        }
    sum+=dist[D];
    return fm*sum;
    }
return 0;
}
void solve()
{
sol=0; drum=1;
while(drum)
    {
    drum=0;
    sol+=dijkstra();
    }
}
void write()
{
freopen("fmcm.out","w",stdout); printf("%d",sol); fclose(stdout);
}
int main()
{
read();
bellman_ford();
solve();
write();
return 0;
}