Cod sursa(job #1885079)

Utilizator antanaAntonia Boca antana Data 19 februarie 2017 16:38:35
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.18 kb
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>

#define MAXN 351
#define MAXM 12501
#define INF 0x3f3f3f3f

using namespace std;

int best[MAXN];

struct nodes{
    int idx, d;

    bool operator < (const nodes &aux) const {
        return d > aux.d;
    }
};

vector <int> G[MAXN];
priority_queue < nodes > heap;

int n, m, source, sink, q[MAXN*MAXN], rl[MAXN], capacity[MAXN][MAXN], flow[MAXN][MAXN], cost[MAXN][MAXN], dist[MAXN], dad[MAXN];
int maxflow, mincost;
bool inq[MAXN];

void bellmanford()
{
    int left, right, i, node, son;

    left = right = 0;
    q[right++] = source;
    dist[source] = 0;
    inq[source] = 1;

    while(left < right)
    {
        node = q[left++];
        inq[node] = 0;

        for(i=0; i<G[node].size(); ++i)
        {
            son = G[node][i];
            if(dist[node] + cost[node][son] < dist[son] && flow[node][son] < capacity[node][son])
            {
                dist[son] = dist[node] + cost[node][son];
                if(!inq[son])
                {
                    q[right++] = son;
                    inq[son] = 1;
                }
            }
        }
    }
}

inline int doCost(int x, int y){
    return cost[x][y] + dist[x] - dist[y];
}

inline bool dijkstra()
{
    int i, sheep, son, minflow, now;
    nodes node;

    for(i=1; i<=n; ++i)
        best[i] = INF;

    best[source] = rl[source] = 0;

    heap.push({source, 0});
    while(!heap.empty())
    {
        node = heap.top();
        heap.pop();

        if(best[node.idx] != node.d) continue;

        for(i=0; i<G[node.idx].size(); ++i)
        {
            son = G[node.idx][i];
            if(best[node.idx] + doCost(node.idx, son) < best[son] && flow[node.idx][son] < capacity[node.idx][son])
            {
                best[son] = best[node.idx] + doCost(node.idx, son);
                rl[son] = rl[node.idx] + cost[node.idx][son];
                dad[son] = node.idx;
                heap.push({son, best[son]});
            }
        }
    }

    if(best[sink] == INF) return 0;

    now = 0;
    minflow = INF;
    for(sheep=sink; sheep!=source; sheep=dad[sheep])
    {
        son = dad[sheep];
        minflow = min(minflow, capacity[son][sheep] - flow[son][sheep]);
        now += cost[son][sheep];
    }

    for(sheep=sink; sheep!=source; sheep=dad[sheep])
    {
        son = dad[sheep];
        flow[son][sheep] += minflow;
        flow[sheep][son] -= minflow;
    }

    maxflow += minflow;
    mincost += rl[sink] * minflow;

    for(i=1; i<=n; ++i)
        dist[i] = rl[i];

    return 1;
}

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

    int i, x, y, p, c;

    scanf("%d%d%d%d", &n, &m, &source, &sink);

    for(i=1; i<=m; ++i)
    {
        scanf("%d%d%d%d", &x, &y, &c, &p);
        G[x].push_back(y);
        G[y].push_back(x);
        capacity[x][y] = c;
        cost[x][y] = p;
        cost[y][x] = -p;
    }

    for(i=1; i<=n; ++i)
        dist[i] = INF;

    bellmanford();

    for(; dijkstra(); );

    printf("%d", mincost);

    return 0;
}