Cod sursa(job #2689479)

Utilizator Constantin.Dragancea Constantin Constantin. Data 21 decembrie 2020 01:21:28
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
#include <bits/stdc++.h>
using namespace std;

const int N = 400;
int n, m, s, d;
vector <int> graph[N];
int cap[N][N], cost[N][N];
queue <int> Q;
priority_queue < pair <int, int> > S;
int old_dist[N], dist[N], pr[N];
bool vis[N];

void Bellman(){
	for (int i = 1; i <= n; ++i){
		old_dist[i] = 1e9;
		vis[i] = 0;
	}
	
	Q.push(s);
	old_dist[s] = 0;
	vis[s] = 1;
	
	while (not Q.empty()){
		int node = Q.front();
		int curr_cost = old_dist[node];
		Q.pop();
		vis[node] = 0;
		
		for (int nei: graph[node]){
			if (!cap[node][nei])
				continue;
			int new_dist = curr_cost + cost[node][nei];
			if (new_dist < old_dist[nei]){
				old_dist[nei] = new_dist;
				if (!vis[nei]){
					Q.push(nei);
					vis[nei] = 1;
				}
			}
		}
	}
	//for (int i = 1; i <= n; ++i)
	//	cout << old_dist[i] << ' ';
	//cout << '\n';
}

int Dijkstra(){
	for (int i = 1; i <= n; ++i)
		dist[i] = 1e9;
	
	S.push({0, s});
	dist[s] = 0;
	
	while (not S.empty()){
		int curr_cost = -S.top().first;
		int node = S.top().second;
		S.pop();
		
		if (curr_cost != dist[node])
			continue;
		
		for (int nei: graph[node]){
			if (!cap[node][nei])
				continue;
			int new_dist = curr_cost + cost[node][nei] + old_dist[node] - old_dist[nei];
			if (new_dist < dist[nei]){
				dist[nei] = new_dist;
				S.push({-dist[nei], nei});
				pr[nei] = node;
			}
		}
	}
	
	if (dist[d] == 1e9)
		return 0;
	
	int flow = 1e9, path_cost = 0;
	for (int node = d; node != s; node = pr[node])
		flow = min(flow, cap[pr[node]][node]);
	
	for (int node = d; node != s; node = pr[node]){
		cap[pr[node]][node] -= flow;
		cap[node][pr[node]] += flow;
		path_cost += cost[pr[node]][node];
		//cout << node << ' ';
	}
	//cout << " cost: " << path_cost << " flow: " << flow << '\n';
	
	for (int i = 1; i <= n; ++i)
		old_dist[i] = dist[i];
	
	return path_cost * flow;
}

int main(){
	ifstream cin("fmcm.in");
	ofstream cout("fmcm.out");
	
	cin >> n >> m >> s >> d;
	while (m--){
		int a, b, c, z;
		cin >> a >> b >> c >> z;
		graph[a].push_back(b);
		graph[b].push_back(a);
		cap[a][b] = c;
		cost[a][b] = z;
		cost[b][a] = -z;
	}
	
	Bellman();
	int ans = 0, path_cost = 0;
	do{
		path_cost = Dijkstra();
		ans += path_cost;
	} while(path_cost);
	
	cout << ans << '\n';
	
	return 0;
}