Cod sursa(job #3154431)

Utilizator tryharderulbrebenel mihnea stefan tryharderul Data 4 octombrie 2023 17:45:26
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 351;

int n, m, source, sink;
int h[NMAX], real_h[NMAX], dist[NMAX], parent[NMAX], cap[NMAX][NMAX];
vector<vector<pair<int, int>>> g;

void bellman_ford(int start_node) {
	fill(h+1, h+n+1, 1e9);
	h[start_node] = 0;
	for(int i = 0; i < n-1; i++) {
		for(int node = 1; node <= n; node++) {
			for(auto [son, w] : g[node])
				if(cap[node][son] > 0 && h[node] + w < h[son])
					h[son] = h[node] + w; 
		}
	}
}

// Dijkstra
bool bfs(int start) {
	priority_queue<pair<int, int>> pq;
	pq.push({0, start});
	fill(dist+1, dist+n+1, INT_MAX);
	dist[start] = 0;
	real_h[start] = 0;
	while(!pq.empty()) {
		int node = pq.top().second;
		pq.pop();
		for(auto [son, w] : g[node]) {
			if(cap[node][son] <= 0 || dist[son] <= dist[node] + w + h[node] - h[son]) continue ;

			dist[son] = dist[node] + w + h[node] - h[son];
			real_h[son] = real_h[node] + w;
			parent[son] = node;
			pq.push({-dist[son], son});
		}
	}
	return dist[sink] != INT_MAX;
}

int flow() {
	int flow_cost = 0;
	while(bfs(source)) {
		int node = sink, curr_flow = INT_MAX;
		while(node != source) {
			curr_flow = min(curr_flow, cap[parent[node]][node]);
			node = parent[node];
		}
		for(int i = 1; i <= n; i++) h[i] = real_h[i];
		node = sink;
		while(node != source) {
			cap[node][parent[node]] += curr_flow;
			cap[parent[node]][node] -= curr_flow;
			node = parent[node];
		}

		flow_cost += curr_flow * h[sink] ;
	}
	return flow_cost;
}

int main() {
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	scanf("%d %d %d %d", &n, &m, &source, &sink);
	g.resize(n+1);
	for(int i = 0; i < m; i++) {
		int x, y, c, w;
		scanf("%d %d %d %d", &x, &y, &c, &w);
		cap[x][y] = c;
		g[x].push_back({y, w});
		g[y].push_back({x, -w}); 
	}

	bellman_ford(source);

	// for(int node = 1; node <= n; node++) printf("%d ", h[node]);
	// puts("");	
	printf("%d\n", flow());

	return 0;
}