Cod sursa(job #768694)

Utilizator auRSTARHreapca Aurelian auRSTAR Data 17 iulie 2012 16:51:04
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 kb
#include<cstdio>
#include<vector>
#include<deque>
#include<bitset>
#define oo 1<<30
#include<algorithm>
using namespace std;
vector<int> V[360];
bitset<360>in_q;
deque<int>Q;
int SOL,n,m,S,D,COST[360][360],C[360][360],F[360][360],cnt,x,y,c,z,i,cost[360],dad[360],H[360],poz[360],dij(),CT,N;
void read(),solve(),heap_up(int),heap_down(int),upd();
int main()
{
    read();
    solve();
    return 0;

}
void read()
{
    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",&x,&y,&c,&z);
        V[x].push_back(y);
        if(!(x==S||y==D))
            V[y].push_back(x);
        C[x][y]=c;
        COST[x][y]=z;
        COST[y][x]=-z;
    }
}
void solve()
{
    Q.push_back(S);
    in_q[S]=1;
    for(i=1;i<=n;i++)cost[i]=oo;
    cost[S]=0;
    for(;!Q.empty();)
    {
        cnt=Q.front();
        for(vector<int>::iterator it=V[cnt].begin();it!=V[cnt].end();it++)
            if(cost[cnt]+COST[cnt][*it]<cost[*it]&&C[cnt][*it])
            {
                cost[*it]=cost[cnt]+COST[cnt][*it];
                if(!in_q[*it])
                {
                    Q.push_back(*it);
                    in_q[*it]=1;
                }
            }
        in_q[cnt]=0;
        Q.pop_front();
    }
    for(i=1;i<=n;i++)
        for(vector<int>::iterator it=V[i].begin();it!=V[i].end();it++)
            COST[i][*it]+=cost[i]-cost[*it];
    CT=cost[S]-cost[D];
    for(;dij();)
        upd();
    printf("%d\n",SOL);
}
int dij()
{
    for(i=1;i<=n;i++)
    {
        cost[i]=oo;
        H[i]=i;
        poz[i]=i;
    }
    H[1]=S;
    H[S]=1;
    poz[1]=S;
    poz[S]=1;
    cost[S]=0;
    N=n;
    for(;N>=1;)
    {
        cnt=H[1];
        for(vector<int>::iterator it=V[cnt].begin();it!=V[cnt].end();it++)
        {
            if(cost[cnt]+COST[cnt][*it]<cost[*it]&&C[cnt][*it]-F[cnt][*it])
            {
                dad[*it]=cnt;
                cost[*it]=cost[cnt]+COST[cnt][*it];
                heap_up(*it);
            }
        }
        H[1]=H[N];poz[H[1]]=1;N--;
        heap_down(1);
    }
    if(cost[D]==oo)return 0;return 1;
}
void heap_up(int X)
{
    for(;X&&cost[H[X]]<cost[H[X>>1]];X>>=1)
    {
       int aux=H[X];H[X]=H[X>>1];H[X>>1]=aux;poz[H[X]]=X;poz[H[X>>1]]=X>>1;
    }
}
void heap_down(int X)
{
    int fiu;
    fiu=2*X;
    if(fiu>N)return;
    if(fiu<N&&cost[H[fiu]]>cost[H[fiu+1]])fiu++;
    if(cost[H[fiu]]<cost[H[X]])
    {
        int aux=H[X];H[X]=H[fiu];H[fiu]=aux;poz[H[X]]=X;poz[H[fiu]]=fiu;
        heap_down(fiu);
    }
}
void upd()
{
    int bc=0,flow=oo;
    cnt=D;
    for(;cnt!=S;cnt=dad[cnt])
    {
        flow=min(flow,C[dad[cnt]][cnt]-F[dad[cnt]][cnt]);
        bc+=COST[dad[cnt]][cnt];
    }
    for(cnt=D;cnt!=S;cnt=dad[cnt])
        F[dad[cnt]][cnt]+=flow;
    SOL+=(bc-CT)*flow;
}