Cod sursa(job #1971354)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 20 aprilie 2017 12:34:42
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.63 kb
#include <fstream>
#include <vector>
#include <queue>

//12:28
using namespace std;

const int NMAX = 350 + 5;
const int MMAX = 12500 + 5;
const int INF = 1E9;

int N, M, S, T;
int cap[NMAX][NMAX];
int cost[NMAX][NMAX];
vector <int> graph[NMAX];

bool inQueue[NMAX];
queue <int> q;
int p[NMAX];
int father[NMAX];

void BF() {
    for (int i = 1; i <= N; ++ i)
        p[i] = INF, father[i] = inQueue[i] = 0;

    q.push(S);
    p[S] = 0;
    inQueue[S] = true;

    while (!q.empty()) {
        int node = q.front();
        q.pop();
        inQueue[node] = false;

        for (auto it: graph[node])
            if (cap[node][it] && p[node] + cost[node][it] < p[it]) {
                p[it] = p[node] + cost[node][it];
                father[it] = node;
                if (!inQueue[it]) {
                    inQueue[it] = true;
                    q.push(it);
                }
            }
    }
}

priority_queue <pair <int, int> > pq;
int dist[NMAX];
bool vis[NMAX];

bool dijkstra() {
    for (int i = 1; i <= N; ++ i)
        dist[i] = INF, vis[i] = false;

    dist[S] = 0;
    pq.push(make_pair(0, S));

    while (!pq.empty()) {
        int node = pq.top().second;
        pq.pop();

        if (vis[node])
            continue;
        vis[node] = true;

        for (auto it: graph[node])
            if (!vis[it] && cap[node][it] && dist[node] + cost[node][it] + p[node] - p[it] < dist[it]) { //Add p
                dist[it] = dist[node] + cost[node][it] + p[node] - p[it];
                father[it] = node;
                pq.push(make_pair(-dist[it], it));
            }
    }

    for (int i = 1; i <= N; ++ i)
        p[i] = dist[i] - (p[S] - p[i]);
    return vis[T];
}

int minCostFlow() {
    int ans = 0;

    BF();
    while (dijkstra()) {
        int node = T;
        int f = INF;
        while (node != S) {
            f = min(f, cap[father[node]][node]);
            node = father[node];
        }

        node = T;
        while (node != S) {
            cap[father[node]][node] -= f;
            cap[node][father[node]] += f;
            ans += cost[father[node]][node] * f;
            node = father[node];
        }
    }
    return ans;
}

int main()
{
    ifstream cin("fmcm.in");
    ofstream cout("fmcm.out");

    cin >> N >> M >> S >> T;

    for (int i = 1; i <= M; ++ i) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        cap[a][b] += c;
        cost[a][b] += d;
        cost[b][a] -= d;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    cout << minCostFlow() << '\n';
    return 0;
}