Cod sursa(job #1601089)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 15 februarie 2016 18:39:08
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <vector>

#define pii pair< int, int >
#define st first
#define nd second

using namespace std;

const int Mn = 355;
const int oo = 1 << 30;

int n, m, s, d, sol, flow;
int parent[Mn], dst[Mn], ds[Mn], newd[Mn];
int cap[Mn][Mn], cost[Mn][Mn];
bool used[Mn];
vector< int > g[Mn];
vector< int > :: iterator it;
queue< int > q;
priority_queue< pii, vector< pii >, greater< pii > > pq;

bool dijkstra()
{
    for (int i = 1; i <= n; i++)
        ds[i] = oo;

    ds[s] = 0;
    newd[s] = 0;
    pq.push(make_pair(0,s));

    while (!pq.empty())
    {
        int a = pq.top().st, b = pq.top().nd;
        pq.pop();

        for (it = g[b].begin(); it != g[b].end(); it++)
            if (cap[b][*it])
            {
                int c = ds[b] + cost[b][*it] + dst[b] - dst[*it];
                if (c < ds[*it])
                {
                    ds[*it] = c;
                    parent[*it] = b;
                    newd[*it] = newd[b] + cost[b][*it];
                    pq.push(make_pair(ds[*it], *it));
                }
            }
    }

    memcpy(dst, newd, sizeof(dst));
    if (ds[d] == oo)
       return 0;

    int mn = oo, cst = 0;
    for (int node = d; node != s; node = parent[node])
        mn = min(mn, cap[parent[node]][node]),
        cst += cost[parent[node]][node];

    flow += mn;
    sol += mn * dst[d];
    for (int node = d; node != s; node = parent[node])
        cap[parent[node]][node] -= mn,
        cap[node][parent[node]] += mn;

    return 1;
}

void bellmanford()
{
    for (int i = 1; i <= n; i++)
        dst[i] = oo;

    dst[s] = 0;
    q.push(s);
    used[s] = 1;

    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        used[x] = 0;

        for (it = g[x].begin();it != g[x].end();it++)
            if (cap[x][*it])
            {
                if (dst[x] + cost[x][*it] >= dst[*it])
                   continue;

                dst[*it] = dst[x] + cost[x][*it];
                if (used[*it])
                   continue;

                used[*it] = 1;
                q.push(*it);
            }
    }
}

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

    scanf("%d %d %d %d",&n, &m, &s, &d);

    for (; m; m--)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        scanf("%d %d", &cap[x][y], &cost[x][y]);
        g[x].push_back(y);
        g[y].push_back(x);
        cost[y][x] = -cost[x][y];
    }

    bellmanford();
    while (dijkstra());

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

  return 0;
}