Pagini recente » Cod sursa (job #822954) | Cod sursa (job #2822193) | Cod sursa (job #2814234) | Cod sursa (job #216011) | Cod sursa (job #1410210)
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int kMaxN = 355;
const int kInf = 0x3f3f3f3f;
int N, M, S, D;
vector<pair<int, int>> G[kMaxN];
int cap[kMaxN][kMaxN];
int cost;
int old_dist[kMaxN], real_dist[kMaxN], positive_dist[kMaxN];
int padre[kMaxN];
bool in_q[kMaxN];
struct HeapNode {
int node, cost;
HeapNode(int n, int c) : node(n), cost(c) {}
bool operator<(const HeapNode &other) const {
return cost > other.cost;
}
};
void Read() {
ifstream fin("fmcm.in");
fin >> N >> M >> S >> D;
while (M--) {
int x, y, c, z;
fin >> x >> y >> c >> z;
G[x].emplace_back(y, z);
G[y].emplace_back(x, -z);
cap[x][y] = c;
}
}
void BellmanFord() {
queue<int> q;
memset(old_dist, kInf, sizeof old_dist);
old_dist[S] = 0;
q.push(S);
in_q[S] = true;
while (!q.empty()) {
int node = q.front();
q.pop();
in_q[node] = false;
for (auto it : G[node])
if (cap[node][it.first] && old_dist[node] + it.second < old_dist[it.first]) {
old_dist[it.first] = old_dist[node] + it.second;
if (!in_q[it.first]) {
q.push(it.first);
in_q[it.first] = true;
}
}
}
}
bool Dijkstra() {
priority_queue<HeapNode> q;
memset(positive_dist, kInf, sizeof positive_dist);
real_dist[S] = 0;
positive_dist[S] = 0;
q.emplace(S, 0);
while (!q.empty()) {
int node = q.top().node;
int cost = q.top().cost;
q.pop();
if (positive_dist[node] != cost)
continue;
for (auto it : G[node]) {
int new_cost = positive_dist[node] + it.second + old_dist[node] - old_dist[it.first];
if (cap[node][it.first] && new_cost < positive_dist[it.first]) {
positive_dist[it.first] = new_cost;
real_dist[it.first] = real_dist[node] + it.second;
padre[it.first] = node;
q.emplace(it.first, new_cost);
}
}
}
memcpy(old_dist, real_dist, sizeof real_dist);
return positive_dist[D] < kInf;
}
void Solve() {
BellmanFord();
while (Dijkstra()) {
int flow = kInf;
for (int i = D; i != S; i = padre[i])
flow = min(flow, cap[padre[i]][i]);
for (int i = D; i != S; i = padre[i]) {
cap[padre[i]][i] -= flow;
cap[i][padre[i]] += flow;
}
cost += flow * real_dist[D];
}
}
int main() {
Read();
Solve();
ofstream("fmcm.out") << cost << "\n";
return 0;
}