Cod sursa(job #721181)

Utilizator ioalexno1Alexandru Bunget ioalexno1 Data 23 martie 2012 13:46:38
Problema Flux maxim de cost minim Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.7 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];
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,x,y;
struct coada{ int v; coada *next; }*st,*dr;
  coada *adr;
  nod *aux;
for(i=1;i<=n;++i)
    {
    dist[i]=inf; viz[i]=0;
    }
dist[S]=0; viz[S]=1;
adr=new coada; adr->v=S; adr->next=NULL; st=dr=adr;
while(st)
    {
    x=st->v;
    for(aux=G[x];aux!=NULL;aux=aux->urm)
        {
        y=aux->val;
        if(cap[x][y]>flux[x][y]&&dist[y]>dist[x]+cost[x][y])
            {
            dist[y]=dist[x]+cost[x][y];
            if(!viz[y])
                {
                adr=new coada; adr->v=y; adr->next=NULL; dr->next=adr; dr=adr;
                viz[y]=1;
                }
            }
        }
    adr=st; st=st->next; delete adr;
    }
sum=dist[D];
}
void dist_positive()
{ int i;
  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];
}
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(fiu<=lgheap&&e)
    {
    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*2;
            }
    }
}
void upinheap(int ind)
{ int tata,fiu,z;
  bool e;
fiu=poz[ind]; tata=fiu/2; 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/2;
            }
    }
}
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;
dist_positive();
for(i=1;i<=n;++i)
    {
    dist[i]=inf; heap[i]=i; poz[i]=i; tata[i]=0;
    }
dist[S]=0; lgheap=n;
heap[1]=S; heap[S]=1;
poz[1]=S; poz[S]=1;
while(lgheap>=1&&dist[heap[1]]!=inf)
    {
    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;
    for(i=D;i!=S;i=tata[i])
        fm=min(fm,cap[tata[i]][i]-flux[tata[i]][i]);
    sum+=dist[D];
    if(fm!=0)
        {
        for(i=D;i!=S;i=tata[i])
            {
            flux[tata[i]][i]+=fm;
            flux[i][tata[i]]-=fm;
            }
        return fm;
        }
    else return 0;
    }
return 0;
}
void solve()
{ int x;
sol=0; x=1;
while(x)
    {
    x=dijkstra();
    sol=sol+x*sum;
    }
}
void write()
{
freopen("fmcm.out","w",stdout); printf("%d",sol); fclose(stdout);
}
int main()
{
read();
bellman_ford();
solve();
write();
return 0;
}