Cod sursa(job #1761420)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 22 septembrie 2016 10:26:17
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

typedef pair<int, int> pii;
typedef pair<int, pii> p3i;

int N, M, S, T, flow, cost;
int cp[405][405];
int cst[405][405];
int cdst[405][405];
int dst[405];
int inq[405];
int f[405];
queue <int> q;
vector <int> edg[405];
priority_queue< p3i, vector <p3i>, greater<p3i> > hp;
int d[405];

void BFS()
{
    memset(f, 0, sizeof(f));
    for(int i = 1; i <= N; i++)
        dst[i] = 1 << 30;
    dst[S] = 0;
    inq[S] = 1;
    f[S] = 0;
    q.push(S);
    while(!q.empty())
    {
        int x = q.front();
        inq[x] = 0;
        q.pop();

        for(auto nxt: edg[x])
        {
            if(cp[x][nxt] == 0) continue;
            int d = dst[x] + cst[x][nxt];
            if(d < dst[nxt])
            {
                dst[nxt] = d;
                f[nxt] = x;
                if(!inq[nxt])
                {
                    q.push(nxt);
                    inq[nxt] = 1;
                }
            }
        }
    }

    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= N; j++)
            cdst[i][j] = cst[i][j] + dst[i] - dst[j];
}

void dijkstra()
{
    memset(f, 0, sizeof(f));
    for(int i = 1; i <= N; i++)
        d[i] = 1 << 30;

    hp.push({0, {S, 0}});
    while(!hp.empty())
    {
        int nod = hp.top().second.first;
        int val = hp.top().first;
        int fth = hp.top().second.second;
        hp.pop();

        if(d[nod] <= val)   continue;
        d[nod] = val;
        f[nod] = fth;

        for(auto nxt: edg[nod])
            if(cp[nod][nxt])
                hp.push({val + cdst[nod][nxt], {nxt, nod}});
    }
}

int main()
{
    #ifdef FILE_IO
    freopen("fmcm.in", "r", stdin);
    freopen("fmcm.out", "w", stdout);
    #endif

    scanf("%d%d%d%d", &N, &M, &S, &T);
    for(int i = 1; i <= M; i++)
    {
        int x, y, cap, cost;
        scanf("%d%d%d%d", &x, &y, &cap, &cost);
        cp[x][y] = cap;
        cp[y][x] = 0;
        cst[x][y] = cost;
        cst[y][x] = -cost;
        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    BFS();

    flow = 0;
    while(1)
    {
        dijkstra();
        if(f[T] == 0)   break;

        int addFlow = 1 << 30;
        int c = 0;
        for(int nod = T; nod != S; nod = f[nod])
        {
            addFlow = min(addFlow, cp[ f[nod] ][nod]);
            c += cst[ f[nod] ][nod];
        }

        flow += addFlow;
        cost += addFlow * c;

        for(int nod = T; nod != S; nod = f[nod])
        {
            cp[ f[nod] ][nod] -= addFlow;
            cp[nod][ f[nod] ] += addFlow;
        }
    }

    printf("%d\n", cost);

    return 0;
}