Cod sursa(job #587830)

Utilizator drywaterLazar Vlad drywater Data 5 mai 2011 23:42:16
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 kb
#include <stdio.h>
#include <vector>
using namespace std;
#define INF 2000000000
int g[360],l,dist[351],drum,sum,k,n,m,s,d,i,j,x,y,z,c,C[351][351],cost[351][351],f[351][351],h[360],p[360],pred[360];
vector <int> A[360];
void push(int x)
{
    int aux;
    while (x/2>1 && dist[h[x]]<dist[h[x/2]])
    {
        aux=h[x];
        h[x]=h[x/2];
        h[x/2]=aux;
        p[h[x/2]]=x/2;
        p[h[x]]=x;
        x/=2;
    }
}
void pop(int x)
{
    int y=0,aux;
    while (x!=y)
    {
        y=x;
        if (y*2<=l && dist[h[y*2]]<dist[h[x]]) x=y*2;
        if (y*2+1<=l && dist[h[y*2+1]]<dist[h[x]]) x=y*2+1;
        aux=h[x];
        h[x]=h[y];
        h[y]=aux;
        p[h[y]]=y;
        p[h[x]]=x;
    }
}
int dijkstra()
{
    for (i=1;i<=n;i++)
    {
        for (k=0;k<g[i];k++)
        {
            y=A[i][k];
            if (dist[i]!=INF && dist[y]!=INF) cost[i][y]+=dist[i]-dist[y];
        }
    }
    for (i=1;i<=n;i++)
    {
        dist[i]=INF;
        h[i]=i;
        p[i]=i;
        pred[i]=-1;
    }
    dist[s]=0;
    h[1]=s; h[s]=1;
    p[1]=s; p[s]=1;
    l=n;
    while (l>1 && dist[h[1]]!=INF)
    {
        for (k=0;k<g[h[1]];k++)
        {
            y=A[h[1]][k];
            if (C[h[1]][y]-f[h[1]][y]>0 && dist[y]>dist[h[1]]+cost[h[1]][y])
            {
                 dist[y]=dist[h[1]]+cost[h[1]][y];
                 pred[y]=h[1];
                 push(p[y]);
            }
        }
    h[1]=h[l--];
    p[h[1]]=1;
    if (l>1) pop(1);
    }
    if (dist[d]!=INF)
    {
        int vmin=INF;
        drum=1;
        for (i=d;i!=s;i=pred[i])
            if (vmin>C[pred[i]][i]-f[pred[i]][i]) vmin=C[pred[i]][i]-f[pred[i]][i];
        for (i=d;i!=s;i=pred[i])
        {
            f[pred[i]][i]+=vmin;
            f[i][pred[i]]-=vmin;
        }
        sum+=dist[d];
        return vmin*sum;
    }
    return 0;
}
long long flux()
{
    long long rez=0;
    drum=1;
    while (drum)
    {
        drum=0;
        rez+=dijkstra();
    }
    return rez;
}
int main(void)
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&s,&d);
    for (i=1;i<=m;i++)
    {
        scanf("%d%d%d%d",&x,&y,&c,&z);
        A[x].push_back(y);
        A[y].push_back(x);
        C[x][y]=c;
        cost[x][y]=z;
        cost[y][x]=-z;
    }
    for (i=1;i<=n;i++) {dist[i]=INF; g[i]=A[i].size();}
    dist[s]=0;
    int stop=0,y;
    for (i=1;i<=n && !stop;i++)
    {
        stop=1;
        for (j=1;j<=n;j++)
        {
            for (k=0;k<g[j];k++)
            {
                y=A[j][k];
                if (C[j][y]-f[j][y]>0 && dist[j]+cost[j][y]<dist[y])
                {
                    stop=0;
                    dist[y]=dist[j]+cost[j][y];
                }
            }
        }
    }
    sum=dist[d];
    printf("%lld\n",flux());
    return 0;
}