Pagini recente » Cod sursa (job #1729799) | Cod sursa (job #190937) | Cod sursa (job #2160945) | Cod sursa (job #2428973) | Cod sursa (job #2959531)
#include <bits/stdc++.h>
using namespace std;
std::vector<std::vector<int>> adj_list;
std::vector<std::vector<int>> capacity;
std::vector<std::vector<int>> price;
std::vector<int> initial_distances;
std::vector<int> positive_distances;
int flow = 0, flow_price = 0;
int n, m, start, finish;
std::vector<int> bellman_ford () {
std::vector<int> distances(n + 1, 1e9);
std::queue<int> updated;
std::vector<bool> in_queue(n + 1, false);
distances[0] = 0;
updated.push(0);
in_queue[0] = true;
while (!updated.empty()) {
int current = updated.front();
updated.pop();
in_queue[current] = false;
for (auto nbh: adj_list[current]) {
if (capacity[current][nbh]) {
if (distances[current] + price[current][nbh] < distances[nbh]) {
distances[nbh] = distances[current] + price[current][nbh];
if (!in_queue[nbh]) {
updated.push(nbh);
in_queue[nbh] = true;
}
}
}
}
}
return distances;
}
int dijkstra () {
std::vector<int> dist(n + 1, 1e9);
std::vector<int> father(n + 1, 0);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> heap_dist;
dist[start] = positive_distances[start] = 0;
heap_dist.push({start, 0});
while (!heap_dist.empty()) {
auto current_node = heap_dist.top().first;
auto current_price = heap_dist.top().second;
heap_dist.pop();
if (dist[current_node] != current_price) continue;
for (auto nbh : adj_list[current_node]) {
if (capacity[current_node][nbh]) {
int new_dist_to_nbh = dist[current_node] + price[current_node][nbh] + initial_distances[current_node] - initial_distances[nbh];
if (new_dist_to_nbh < dist[nbh]) {
dist[nbh] = new_dist_to_nbh;
father[nbh] = current_node;
positive_distances[nbh] = positive_distances[current_node] + price[current_node][nbh];
heap_dist.push({nbh, dist[nbh]});
}
}
}
}
if (dist[finish] == 1e9) return false;
int path_capacity = 1e9, path_price = 0;
int current = finish;
while (current != start) {
path_capacity = min(path_capacity, capacity[father[current]][current]);
path_price += price[father[current]][current];
current = father[current];
}
flow += path_capacity;
flow_price += path_capacity * positive_distances[finish];
current = finish;
while (current != start) {
capacity[current][father[current]] += path_capacity;
capacity[father[current]][current] -= path_capacity;
current = father[current];
}
return true;
}
int main()
{
std::ifstream fin("fmcm.in");
std::ofstream fout("fmcm.out");
fin >> n >> m >> start >> finish;
adj_list.resize(n + 1);
capacity.resize(n + 1, std::vector<int>(n + 1, 0));
price.resize(n + 1, std::vector<int>(n + 1, 0));
for (int i = 1; i <= m; ++i) {
int source, dest, cap, cost;
fin >> source >> dest >> cap >> cost;
adj_list[source].push_back(dest);
adj_list[dest].push_back(source);
capacity[source][dest] = cap;
price[source][dest] = cost;
price[dest][source] = -cost;
}
initial_distances = bellman_ford();
positive_distances.resize(n + 1, 1e9);
while (dijkstra());
fout << flow_price;
return 0;
}