Pagini recente » Cod sursa (job #153739) | Cod sursa (job #1507821) | Cod sursa (job #845994) | Cod sursa (job #2318519) | Cod sursa (job #2255817)
#include <bits/stdc++.h>
#define MaxN 355
#define inf (1<<30)
std::ifstream InFile("fmcm.in");
std::ofstream OutFile("fmcm.out");
int N, M, S, D;
int FlowCost;
int Parent[MaxN], BFDist[MaxN];
int Dist[MaxN], Real_Dist[MaxN];
int Cost[MaxN][MaxN],
Capacity[MaxN][MaxN],
Flow[MaxN][MaxN];
std::vector <int> G[MaxN];
std::priority_queue <std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> PQueue;
std::queue <int> Queue;
bool InQueue[MaxN];
inline void AddEdge(int x, int y, int c, int z) {
Capacity[x][y] = c;
Cost[x][y] = z;
Cost[y][x] = -z;
G[x].push_back(y);
G[y].push_back(x);
}
void BellmanFord() {
for (int i=0; i<N; ++i)
BFDist[i] = inf;
Queue.push(S);
BFDist[S] = 0;
InQueue[S] = 1;
int Front;
while (!Queue.empty()) {
Front = Queue.front();
Queue.pop();
InQueue[Front] = 0;
for (auto Vecin:G[Front]) {
if (BFDist[Front] + Cost[Front][Vecin] < BFDist[Front] && Flow[Front][Vecin] < Capacity[Front][Vecin]) {
BFDist[Vecin] = BFDist[Front] + Cost[Front][Vecin];
if (!InQueue[Vecin]) {
InQueue[Vecin] = 1;
Queue.push(Vecin);
}
}
}
}
}
int Dijkstra() {
for (int i = 1; i <= N; ++i) {
Dist[i] = inf;
Real_Dist[i] = inf;
Parent[i] = inf;
}
PQueue.push({0, S});
Dist[S] = 0;
Real_Dist[S] = 0;
Parent[S] = 0;
while (!PQueue.empty()) {
auto tmp = PQueue.top();
PQueue.pop();
auto dist = tmp.first;
auto node = tmp.second;
if (Dist[node] < dist) {
continue;
}
for (auto it : G[node]) {
long long d_aux = 1LL * Dist[node] + Cost[node][it] + BFDist[node] - BFDist[it];
if (d_aux < 1LL * Dist[it] && Flow[node][it] < Capacity[node][it]) {
Dist[it] = d_aux;
Real_Dist[it] = Real_Dist[node] + Cost[node][it];
Parent[it] = node;
PQueue.push({Dist[it], it});
}
}
}
for (int i = 1; i <= N; ++i) {
BFDist[i] = Real_Dist[i];
}
if(Dist[D] == inf) return false;
int minFlow = inf;
for (auto node = D; node != S; node = Parent[node]) {
minFlow = std::min(minFlow, Capacity[Parent[node]][node] - Flow[Parent[node]][node]);
}
if (minFlow > 0) {
FlowCost += minFlow * Real_Dist[D];
for (auto node = D; node != S; node = Parent[node]) {
Flow[Parent[node]][node] += minFlow;
Flow[node][Parent[node]] -= minFlow;
}
}
return true;
return Dist[D] != inf;
}
void Rezolvare() {
BellmanFord();
while (Dijkstra());
OutFile << FlowCost << "\n";
}
void Citire() {
InFile >> N >> M >> S >> D;
for (int i=0, x, y, c, z; i<M; ++i) {
InFile >> x >> y >> c >> z;
AddEdge(x, y, c, z);
}
}
int main() {
Citire();
Rezolvare();
return 0;
}