Cod sursa(job #728401)

Utilizator ioalexno1Alexandru Bunget ioalexno1 Data 28 martie 2012 18:24:41
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.31 kb
#include <cstdio>
#include <vector>
#define N 405
#define inf 1999999999
using namespace std;
vector <int> nod[N];
vector <int>::iterator it;
int cost[N][N],cap[N][N],dist[N],flux[N][N];
int heap[N],lgheap,poz[N],tata[N],c[N*N];
int n,m,S,D,sum,sol;
bool viz[N],drum;
void read()
{ int i,x,y,z,t;
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);
    nod[x].push_back(y);
    nod[y].push_back(x);
    cost[x][y]=t; cost[y][x]=-t; cap[x][y]=z;
    }
fclose(stdin);
}
void bellman_ford()
{ int i,p,u,x,y;
for(i=1;i<=n;++i){ dist[i]=inf; viz[i]=0; }
dist[S]=0;
p=u=1; c[1]=S; viz[S]=1;
while(p<=u)
    {
    x=c[p]; viz[x]=0;
    for(it=nod[x].begin();it!=nod[x].end();++it)
        {
        y=*it;
        if(cap[x][y]>flux[x][y]&&dist[x]+cost[x][y]<dist[y])
                {
                dist[y]=dist[x]+cost[x][y];
                if(viz[y]==0){ c[++u]=y; viz[y]=1; }
                }
        }
    ++p;
    }
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;
for(i=1;i<=n;++i)
    for(it=nod[i].begin();it!=nod[i].end();++it)
        if(dist[i]!=inf&&dist[*it]!=inf)cost[i][*it]+=dist[i]-dist[*it];
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(it=nod[x].begin();it!=nod[x].end();++it)
        {
        y=*it;
        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;
}