Cod sursa(job #2890052)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 14 aprilie 2022 11:19:03
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.58 kb
#include <bits/stdc++.h>

using namespace std;

#pragma GCC optimize("Ofast")

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

const int INF = 1e9;

int n, m, ans, cost, s, d;

vector<bool> inQ;
vector<int> dist, potential, parent;
vector<vector<pair<int, int>>> adj, adj_help;
vector<vector<int>> capacity, flow;

struct compare {
	bool operator () (int a, int b) {
		return dist[a] > dist[b];
	}
};

void bf() {
	adj_help = adj;

	for(int node = 1; node <= n; node++) {
		adj_help[0].push_back({node, 0});
		adj_help[node].push_back({0, 0});
	}

	inQ = vector<bool> (n + 1, 0);
	potential = vector<int> (n + 1, INF);
	queue<int> q;

	q.push(0);
	inQ[0] = 1;
	potential[0] = 0;

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

		for(auto it: adj[node]) {
			if(flow[node][it.first] == capacity[node][it.first]) {
				continue;
			}

			if(potential[it.first] > potential[node] + it.second) {
				potential[it.first] = potential[node] + it.second;

				if(!inQ[it.first]) {
					q.push(it.first);
					inQ[it.first] = 1;
				}
			}
		}
	}
}

bool dij(int s, int d) {
	parent = vector<int> (n + 1, -1);
	inQ = vector<bool> (n + 1, 0);
	dist = vector<int> (n + 1, INF);
	priority_queue<int, vector<int>, compare> pq;

	pq.push(s);
	inQ[s] = 1;
	dist[s] = 0;

	while(!pq.empty()) {
		int node = pq.top();
		pq.pop();
		inQ[node] = 0;

		for(auto it: adj[node]) {
			if(flow[node][it.first] == capacity[node][it.first]) {
				continue;
			}

			if(dist[it.first] > dist[node] + it.second + potential[node] - potential[it.first]) {
				dist[it.first] = dist[node] + it.second + potential[node] - potential[it.first];
				parent[it.first] = node;

				if(!inQ[it.first]) {
					pq.push(it.first);
					inQ[it.first] = 1;
				}
			}
		}
	}

	return dist[d] != INF;
}


int main() {
	fin >> n >> m >> s >> d;

	adj = vector<vector<pair<int, int>>> (n + 1);
	capacity = vector<vector<int>>(n + 1, vector<int> (n + 1, 0));
	flow = vector<vector<int>>(n + 1, vector<int> (n + 1, 0));
	
	for(int i = 1; i <= m; i++) {
		int x, y, c, z;
	
		fin >> x >> y >> c >> z;
		
		capacity[x][y] = c;
		adj[x].push_back({y, z});
		adj[y].push_back({x, -z});
	}

	bf();

	while(dij(s, d)) {
		int maxflow = INF;

		for(int p = d; p != s; p = parent[p]) {
			maxflow = min(maxflow, capacity[parent[p]][p] - flow[parent[p]][p]);
			
			if(maxflow == 0) {
				break;
			}
		}

		if(maxflow == 0) {
			continue;
		}

		for(int p = d; p != s; p = parent[p]) {
			flow[p][parent[p]] -= maxflow;
			flow[parent[p]][p] += maxflow;
		}
	
		ans += maxflow;
		cost += maxflow * dist[d];
	}

	fout /*<< ans << " "*/ << cost << '\n';
	return 0;
}