Cod sursa(job #611721)

Utilizator proflaurianPanaete Adrian proflaurian Data 2 septembrie 2011 20:37:55
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.49 kb
#include<cstdio>
#include<vector>
#include<deque>
#define M 25010
#define N 351
using namespace std;
int n,m,s,d,i,j,k,cp,cs,cap[N][N],flow[N][N],q[N],dad[N],P[N],price[N][N],PRICE,djikstra(),LH,H[N],PH[N],oo=2000000000;
vector<int> v[N];
deque<int> Q;
void upd(),bellman(),HD(int),HU(int);
int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    scanf("%d%d%d%d",&n,&m,&s,&d);
    for(;m;m--)
    {
        scanf("%d%d%d%d",&i,&j,&cp,&cs);cap[i][j]=cp;
        price[i][j]=cs;price[j][i]=-cs;
        v[i].push_back(j);v[j].push_back(i);
    }
    bellman();
    for(;djikstra();)upd();
    printf("%d\n",PRICE);
    return 0;
}
void bellman()
{
    for(i=1;i<=n;i++)P[i]=oo;P[s]=0;dad[s]=s;dad[d]=0;
    Q.resize(0);Q.push_back(s);q[s]=1;
    for(;Q.size();)
    {
        m=Q.front();
        for(vector<int>:: iterator it=v[m].begin();it!=v[m].end();it++)
            if(cap[m][*it]-flow[m][*it]>0&&P[*it]>P[m]+price[m][*it])
            {
                if(!q[*it]){q[*it]=1;Q.push_back(*it);}
                dad[*it]=m;
                P[*it]=P[m]+price[m][*it];
            }
        Q.pop_front();q[m]=0;
    }
    cs=P[d];
}
int djikstra()
{
    for(i=1;i<=n;i++)
    {
        if(P[i]==oo)continue;
        for(vector<int>::iterator it=v[i].begin();it!=v[i].end();it++)
        {
            if(P[*it]==oo)continue;
            price[i][*it]+=P[i]-P[*it];
        }
    }
    for(i=1;i<=n;i++){P[i]=oo;dad[i]=H[i]=PH[i]=i;}
    P[s]=0;H[s]=PH[s]=1;H[1]=PH[1]=s;
    for(LH=n;LH&&P[H[1]]<oo;)
    {
        i=H[1];H[1]=H[LH];PH[H[1]]=1;LH--;HD(1);
        for(vector<int>::iterator it=v[i].begin();it!=v[i].end();it++)
            if(flow[i][*it]<cap[i][*it])
                if(P[*it]>P[i]+price[i][*it])
                {
                    P[*it]=P[i]+price[i][*it];
                    HU(PH[*it]);
                    dad[*it]=i;
                }
    }
    return P[d]==oo?0:1;
}
void upd()
{
    cs+=P[d];
    for(m=oo,i=d,j=dad[d];i-j;i=dad[i],j=dad[j])m=min(m,cap[j][i]-flow[j][i]);
    PRICE+=m*cs;
    for(i=d,j=dad[d];i-j;i=dad[i],j=dad[j]){flow[i][j]-=m;flow[j][i]+=m;}
}
void HU(int F)
{
    int T=F>>1,A;
    if(!T)return;
    if(P[H[T]]<=P[H[F]])return;
    A=H[F];H[F]=H[T];H[T]=A;PH[H[T]]=T;PH[H[F]]=F;HU(T);
}
void HD(int T)
{
    int F=T<<1,A;
    if(F>LH)return;
    if(F<LH) if(P[H[F+1]]<P[H[F]])F++;
    if(P[H[F]]>=P[H[T]])return;
    A=H[F];H[F]=H[T];H[T]=A;PH[H[T]]=T;PH[H[F]]=F;HD(F);
}