Cod sursa(job #1147751)

Utilizator andreiiiiPopa Andrei andreiiii Data 20 martie 2014 09:11:13
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.18 kb
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <bitset>
#include <queue>

using namespace std;

const int N=355, INF=0x3f3f3f3f;

vector <int> G[N];
int C[N][N], F[N][N], Cost[N][N], old_c[N], new_c[N], dist[N], poz[N], h[N], Tr[N];
int n, S, D, flow, flow_cost;

void upheap(int k)
{
    int f;
    while(k>1)
    {
        f=k/2;
        if(dist[h[k]]<dist[h[f]])
        {
            poz[h[k]]=f;
            poz[h[f]]=k;
            swap(h[k], h[f]);
            k=f;
        }
        else return;
    }
}

void downheap(int k)
{
    int f;
    while(k<=h[0])
    {
        f=2*k;
        if(f<=h[0])
        {
            if(f+1<=h[0]&&dist[h[f+1]]<dist[h[f]]) f++;
        }
        else return;
        if(dist[h[f]]<dist[h[k]])
        {
            poz[h[f]]=k;
            poz[h[k]]=f;
            swap(h[k], h[f]);
            k=f;
        }
        else return;
    }
}

bool dijkstra()
{
    int x, cst, fmin, i;
    memset(dist, INF, sizeof(dist));
    memset(poz, 0xff, sizeof(poz));
    poz[S]=1;
    dist[S]=0;
    h[++h[0]]=S;
    while(h[0])
    {
        x=h[1];
        h[1]=h[h[0]];
        h[0]--;
        downheap(1);
        for(vector <int>::iterator it=G[x].begin();it!=G[x].end();it++)
        {
            if(C[x][*it]==F[x][*it]) continue;
            cst=dist[x]+Cost[x][*it]+old_c[x]-old_c[*it];
            if(cst<dist[*it])
            {
                dist[*it]=cst;
                new_c[*it]=new_c[x]+Cost[x][*it];
                Tr[*it]=x;
                if(poz[*it]==-1)
                {
                    h[++h[0]]=*it;
                    poz[*it]=h[0];
                }
                upheap(poz[*it]);
            }
        }
    }
    memcpy(old_c, new_c, sizeof(old_c));
    if(dist[D]==INF) return false;
    for(i=D;i!=S;i=Tr[i])
    {
        fmin=min(fmin, C[Tr[i]][i]-F[Tr[i]][i]);
    }
    flow+=fmin;
    flow_cost+=fmin*new_c[D];
    for(i=D;i!=S;i=Tr[i])
    {
        F[Tr[i]][i]+=fmin;
        F[i][Tr[i]]-=fmin;
    }
    return true;
}

bool bellman_ford()
{
    int x;
    bitset <N> v;
    queue <int> Q;
    memset(old_c, INF, sizeof(old_c));
    old_c[S]=0;
    for(Q.push(S);!Q.empty();Q.pop())
    {
        x=Q.front();
        v[x]=0;
        for(vector <int>::iterator it=G[x].begin();it!=G[x].end();it++)
        {
            if(!C[x][*it]) continue;
            if(old_c[x]+Cost[x][*it]<old_c[*it])
            {
                old_c[*it]=old_c[x]+Cost[x][*it];
                if(!v[*it])
                {
                    v[*it]=1;
                    Q.push(*it);
                }
            }
        }
    }
    if(old_c[D]==INF) return false;
    return true;
}

int main()
{
    freopen("fmcm.in", "r", stdin);
    freopen("fmcm.out", "w", stdout);
    int m, x, y;
    scanf("%d%d%d%d", &n, &m, &S, &D);
    while(m--)
    {
        scanf("%d%d", &x, &y);
        G[x].push_back(y);
        G[y].push_back(x);
        scanf("%d%d", &C[x][y], &Cost[x][y]);
        Cost[y][x]=-Cost[x][y];
    }
    bellman_ford();
    while(dijkstra());
    printf("%d\n", flow_cost);
}