Pagini recente » Cod sursa (job #2186742) | Cod sursa (job #193014) | Cod sursa (job #2891053) | Cod sursa (job #163687) | Cod sursa (job #2959558)
#include <bits/stdc++.h>
using namespace std;
std::vector<int> bellman_ford (std::vector<std::vector<int>> &nodes_list,
std::vector<std::vector<int>> &capacity,
std::vector<std::vector<int>> &price) {
int n = nodes_list.size();
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: nodes_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<std::vector<int>> &nodes_list,
std::vector<std::vector<int>> &capacity,
std::vector<std::vector<int>> &price,
std::vector<int> &initial_distances,
std::vector<int> &positive_distances,
std::vector<int> &father,
int start, int finish,
int &flow, int &flow_price) {
int n = nodes_list.size();
std::vector<int> dist(n, 1e9);
priority_queue<int, vector<int>, greater<>> heap_dist;
dist[start] = positive_distances[start] = 0;
heap_dist.push(start);
while (!heap_dist.empty()) {
auto current_node = heap_dist.top();
heap_dist.pop();
for (auto nbh : nodes_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);
}
}
}
}
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");
int n, m, start, finish;
fin >> n >> m >> start >> finish;
std::vector<std::vector<int>> adj_list(n + 1);
std::vector<std::vector<int>> capacity(n + 1, std::vector<int>(n + 1, 0));
std::vector<std::vector<int>> price(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;
}
auto initial_distances = bellman_ford(adj_list, capacity, price);
std::vector<int> positive_distances(n + 1, 1e9);
int flow = 0, flow_price = 0;
std::vector<int> father(n + 1, 0);
while (dijkstra(adj_list, capacity, price, initial_distances, positive_distances, father, start, finish, flow, flow_price));
fout << flow_price;
return 0;
}