Pagini recente » Cod sursa (job #1885899) | Cod sursa (job #2003511) | Cod sursa (job #2179432) | Cod sursa (job #350460) | Cod sursa (job #2255835)
#include <bits/stdc++.h>
#define MaxN 355
#define inf (int)(1e9)
std::ifstream InFile("fmcm.in");
std::ofstream OutFile("fmcm.out");
int M, S, D;
std::priority_queue <std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<std::pair<int, int>>> PQueue;
std::pair <int, int> Top;
std::queue <int> Queue;
bool InQueue[MaxN];
class DirectedGraph {
public:
int FlowCost;
int N;
inline void AddEdge(int x, int y, int c, int z) {
Capacity[x][y] = c;
Cost[x][y] = z;
Cost[y][x] = -z;
Node[x].ADC.push_back(y);
Node[y].ADC.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:Node[Front].ADC) {
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);
}
}
}
}
}
inline bool Dijkstra() {
for (int i=0; i<N; ++i)
Dist[i+1] = inf,
Real_Dist[i+1] = inf;
PQueue.push({0, S});
Real_Dist[S] = 0;
Dist[S] = 0;
while (!PQueue.empty()) {
Top = PQueue.top();
PQueue.pop();
if (Dist[Top.second] < Top.first) continue;
for (auto Vecin:Node[Top.second].ADC) {
if (Dist[Top.second] + Cost[Top.second][Vecin] + BFDist[Top.second] - BFDist[Vecin] < 1LL * Dist[Vecin] && Flow[Top.second][Vecin] < Capacity[Top.second][Vecin]) {
Dist[Vecin] = Dist[Top.second] + Cost[Top.second][Vecin] + BFDist[Top.second] - BFDist[Vecin];
Real_Dist[Vecin] = Real_Dist[Top.second] + Cost[Top.second][Vecin];
Parent[Vecin] = Top.second;
PQueue.push({Dist[Vecin], Vecin});
}
}
}
for (int i=0; i<N; ++i) // !!!!!!!!!!!!!!!!!!! SUPER SUPER SUPER SUPER SUPER SUPER SUPER SUPER IMPORTANT !!!!!!!!!!!!!!!!!!!
BFDist[i+1] = Real_Dist[i+1];
if(Dist[D] == inf) return false;
int MinFlow = inf;
for (auto x = D; x != S; x = Parent[x])
MinFlow = std::min(MinFlow, Capacity[Parent[x]][x] - Flow[Parent[x]][x]);
if (MinFlow > 0) {
FlowCost += MinFlow * Real_Dist[D];
for (auto x = D; x != S; x = Parent[x]) {
Flow[Parent[x]][x] += MinFlow;
Flow[x][Parent[x]] -= MinFlow;
}
}
return true;
}
private:
int Parent[MaxN],
BFDist[MaxN];
int Dist[MaxN],
Real_Dist[MaxN];
int Cost[MaxN][MaxN],
Capacity[MaxN][MaxN],
Flow[MaxN][MaxN];
struct GraphNode {
std::vector <int> ADC;
} Node[MaxN];
} Graph;
void Rezolvare() {
Graph.BellmanFord();
while (Graph.Dijkstra());
OutFile << Graph.FlowCost << "\n";
}
void Citire() {
InFile >> Graph.N >> M >> S >> D;
for (int i=0, x, y, c, z; i<M; ++i) {
InFile >> x >> y >> c >> z;
Graph.AddEdge(x, y, c, z);
}
}
int main() {
Citire();
Rezolvare();
return 0;
}