Cod sursa(job #1167090)

Utilizator andreiiiiPopa Andrei andreiiii Data 4 aprilie 2014 12:35:43
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.51 kb
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <bitset>
#include <vector>
#include <queue>
#define PII pair<int, int>
#define x first
#define y second
#define mp make_pair

using namespace std;

const int N=355, INF=0x3f3f3f3f;

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

struct comp{
    bool operator()(const PII &a, const PII &b) const
    {
        return a>b;
    }
};

bool bellman_ford()
{
    int nod;
    memset(old_c, INF, sizeof(old_c));
    old_c[S]=0;
    queue <int> Q;
    for(Q.push(S);!Q.empty();Q.pop())
    {
        nod=Q.front();
        v[nod]=0;
        for(auto p: G[nod])
        {
            if(!C[nod][p]) continue;
            if(old_c[p]>old_c[nod]+Cost[nod][p])
            {
                old_c[p]=old_c[nod]+Cost[nod][p];
                if(!v[p])
                {
                    v[p]=1;
                    Q.push(p);
                }
            }
        }
    }
    return (old_c[D]!=INF);
}

bool dijkstra()
{
    int i, nod, d, cst, fmin;
    priority_queue <PII, vector<PII>, comp> H;
    memset(dist, INF, sizeof(dist));
    dist[S]=0;
    for(H.push(mp(0, S));!H.empty();)
    {
        nod=H.top().second;
        d=H.top().first;
        H.pop();
        if(dist[nod]!=d) continue;
        for(auto p: G[nod])
        {
            if(C[nod][p]==F[nod][p]) continue;
            cst=dist[nod]+Cost[nod][p]+old_c[nod]-old_c[p];
            if(dist[p]>cst)
            {
                dist[p]=cst;
                new_c[p]=new_c[nod]+Cost[nod][p];
                Tr[p]=nod;
                H.push(mp(dist[p], p));
            }
        }
    }
    memcpy(old_c, new_c, sizeof(old_c));
    if(dist[D]==INF) return false;
    fmin=INF;
    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;
}

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