Cod sursa(job #1502832)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 15 octombrie 2015 00:42:09
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.22 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <cstdlib>

using namespace std;

const int NMAX = 355;
const int inf = 2e9 + 5;

int n, m, s, t;
vector <int> graph[NMAX];

int cap[NMAX][NMAX];
int cost[NMAX][NMAX];

queue <int> coada;
bool in_queue[NMAX];
int potential[NMAX];

inline void bellman () {
    for (int i = 1; i <= n; ++ i) {
        in_queue[i] = false;
        potential[i] = inf;
    }

    in_queue[s] = true;
    potential[s] = 0;
    coada.push(s);

    int y;
    while (!coada.empty()) {
        y = coada.front();
        coada.pop();
        in_queue[y] = false;

        for (auto it: graph[y])
            if (cap[y][it] && potential[y] + cost[y][it] < potential[it]) {
                potential[it] = potential[y] + cost[y][it];

                if (!in_queue[it]) {
                    in_queue[it] = true;
                    coada.push(it);
                }
            }
    }
}

int father[NMAX];
int dist[NMAX];
priority_queue <pair <int, int> > coada2;

bitset <NMAX> vis;

inline bool dijkstra () {
    for (int i = 1; i <= n; ++ i) {
        father[i] = 0;
        dist[i] = inf;
    }
    memset(father, 0, sizeof(father));

    vis &= 0;

    coada2.push(make_pair(0, s));
    dist[s] = 0;

    int y;
    while (!coada2.empty()) {
        y = coada2.top().second;
        coada2.pop();

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

        for (auto it: graph[y]) {
            if (cap[y][it]) {
                assert(cost[y][it] + potential[y] - potential[it] >= 0);

                if (dist[y] + cost[y][it] + potential[y] - potential[it] < dist[it]) {
                    dist[it] = dist[y] + cost[y][it] + potential[y] - potential[it];
                    father[it] = y;
                    coada2.push(make_pair(-dist[it], it));
                }
            }
        }
    }

    for (int i = 1; i <= n; ++ i)
        dist[i] -= (potential[s] - potential[i]);
    memcpy (potential, dist, sizeof (dist));

    return vis[t];
}

inline int mincost_flow () {
    int flow = 0;
    int suma = 0;

    while (dijkstra()) {
        int node = t;
        int minim = inf;

        while (father[node]) {
            if (cap[father[node]][node] < minim)
                minim = cap[father[node]][node];
            node = father[node];
        }

        flow += minim;
        node = t;

        while (father[node]) {
            cap[father[node]][node] -= minim;
            cap[node][father[node]] += minim;

            suma += minim * cost[father[node]][node];

            node = father[node];
        }
    }

    return suma;
}

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

    cin >> n >> m >> s >> t;

    int x, y, c, d;
    while (m --) {
        cin >> x >> y >> c >> d;

        cap[x][y] += c;

        cost[x][y] = d;
        cost[y][x] = -d;

        graph[x].push_back(y);
        graph[y].push_back(x);
    }

    bellman();

    cout << mincost_flow() << '\n';

    cin.close();
    cout.close();
    return 0;
}