Cod sursa(job #2658427)

Utilizator akumariaPatrascanu Andra-Maria akumaria Data 13 octombrie 2020 22:57:21
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.95 kb
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>
#include <queue>


using namespace std;

#define INF 1<<31 - 1
#define MAXN 352

int cap[MAXN][MAXN];
int cost[MAXN][MAXN];

vector<vector<int>> arcs;
int parents[MAXN], d[MAXN], old_d[MAXN], real_d[MAXN];
bool in_queue[MAXN];


priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;

int n, flow, source, dest;

void bellmanford() {
    memset(old_d, 0x3f, sizeof(old_d));
	old_d[source] = 0;
    in_queue[source] = 1;

	int next_node, current_node;

	queue<int> q;
	q.push(source);

	while(q.size()) {
		current_node = q.front();
		q.pop();

		for(int i=0; i<arcs[current_node].size(); ++i) {
			next_node = arcs[current_node][i];

			if (cap[current_node][next_node]) {
				if (old_d[current_node] + cost[current_node][next_node] < old_d[next_node]) {
					old_d[next_node] = old_d[current_node] + cost[current_node][next_node];
					if (! in_queue[next_node]) {
                        in_queue[next_node] = true;
						q.push(next_node);
					}
				}
			}
		}
	}
}


bool dijkstra() {
	int current_node, next_node, current_cost, current_d;
    memset(d, 0x3f, sizeof(d));
	d[source] = 0;
    real_d[source] = 0;

	pq.push(pair<int, int>(d[source], source));


	while( pq.size() ) {
		current_node = pq.top().second;
		current_cost = pq.top().first;
		pq.pop();

		if (d[current_node] == current_cost)
			for(int i=0; i<arcs[current_node].size(); ++i)
                if (cap[current_node][arcs[current_node][i]]) {
                    next_node = arcs[current_node][i];
                    current_d = d[current_node] + cost[current_node][next_node] + old_d[current_node] - old_d[next_node];

                    if (current_d < d[next_node]) {
                        d[next_node] = current_d;
                        real_d[next_node] = real_d[current_node] + cost[current_node][next_node];
                        parents[next_node] = current_node;

                        pq.push(pair<int, int>(d[next_node], next_node));
                    }
                }
	}
	if (d[dest] == 0x3f3f3f3f)
		return false;

    memcpy(old_d, real_d, sizeof(real_d));
	current_d = INF;
	for(int i=dest; i!= source; i = parents[i])
		if (cap[parents[i]][i] < current_d)
			current_d = cap[parents[i]][i];

	flow += current_d * real_d[dest];
	for(int i=dest; i!= source; i = parents[i]) {
		cap[parents[i]][i] -= current_d;
		cap[i][parents[i]] += current_d;
	}

	return true;
}



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

	int m, a, b, c, e;
	scanf("%d%d%d%d", &n, &m, &source, &dest);

	arcs.resize(n+1);

	for(int i=0; i<m; ++i) {
		scanf("%d%d%d%d", &a, &b, &c, &e);

		arcs[a].push_back(b);
		arcs[b].push_back(a);

		cap[a][b] += c;
		cost[a][b] += e;
		cost[b][a] -= e;
	}

	bellmanford();
	while(dijkstra());

	printf("%d\n", flow);
	return 0;
}