Pagini recente » Cod sursa (job #476506) | Cod sursa (job #431298) | Cod sursa (job #272445) | Profil FlorinSalam | Cod sursa (job #2962718)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
struct Edge {
int nod, cost;
const bool operator< (const Edge &other) const {
return cost > other.cost;
}
};
const int oo = 1e9;
int n, m, source, dest;
vector <vector <int>> cap, cst;
vector<vector<int> > v;
vector <int> oldDistances, realDistances;
int minCostFlow, flow;
void init() {
cap = vector <vector<int>> (n + 1, vector <int> (n + 1));
cst = vector <vector<int>> (n + 1, vector <int> (n + 1));
v = vector <vector <int>> (n + 1);
oldDistances = vector <int> (n + 1, oo);
realDistances = vector <int> (n + 1, oo);
}
void read() {
fin >> n >> m >> source >> dest;
init();
int x, y, capacity, cost;
for (int i = 1; i <= m; ++i) {
fin >> x >> y >> capacity >> cost;
v[x].push_back(y);
v[y].push_back(x);
cap[x][y] = capacity;
cst[x][y] = cost;
cst[y][x] = -cost;
}
}
void bellmanFord() {
queue <int> q;
vector <bool> inQueue(n + 1);
oldDistances[source] = 0;
q.push(source);
while (!q.empty()) {
int node = q.front();
q.pop();
inQueue[node] = false;
for (auto neighbor: v[node]) {
if (cap[node][neighbor]) {
if (oldDistances[node] + cst[node][neighbor] < oldDistances[neighbor]) {
oldDistances[neighbor] = oldDistances[node] + cst[node][neighbor];
if (!inQueue[neighbor]) {
q.push(neighbor);
inQueue[neighbor] = true;
}
}
}
}
}
}
bool dijkstra() {
vector <int> d(n + 1, oo);
vector <int> t(n + 1);
priority_queue<Edge> pq;
d[source] = 0;
realDistances[source] = 0;
pq.push({source, 0});
int node, dist, otherDist;
while(!pq.empty()) {
node = pq.top().nod;
dist = pq.top().cost;
pq.pop();
if(d[node] != dist)
continue;
for(const auto& neighbor : v[node]) {
if(cap[node][neighbor]) {
otherDist = d[node] + cst[node][neighbor] + oldDistances[node] - oldDistances[neighbor];
if(otherDist < d[neighbor]) {
d[neighbor] = otherDist;
realDistances[neighbor] = realDistances[node] + cst[node][neighbor];
t[neighbor] = node;
pq.push({neighbor, d[neighbor]});
}
}
}
}
if(d[dest] == oo)
return false;
int path_capacity = 1e9, path_price = 0;
for (int node = dest; node != source; node = t[node]) {
if (cap[t[node]][node] < path_capacity)
path_capacity = cap[t[node]][node];
path_price += cst[t[node]][node];
}
flow += path_capacity;
minCostFlow += path_capacity * realDistances[dest];
for (int node = dest; node != source; node = t[node]) {
cap[t[node]][node] -= path_capacity;
cap[node][t[node]] += path_capacity;
}
return true;
}
int main()
{
read();
bellmanFord();
while (dijkstra());
fout << minCostFlow;
return 0;
}