Pagini recente » Cod sursa (job #1085521) | Borderou de evaluare (job #207838) | Cod sursa (job #2516750) | Borderou de evaluare (job #2280133) | Cod sursa (job #2962623)
#include <iostream>
#include <fstream>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
ifstream in("fmcm.in");
ofstream out("fmcm.out");
const int NMAX = 356, INF = 2e9;
int N, M, TotalFlow, Source, Destination, Cost[NMAX][NMAX], Graph[NMAX][NMAX], Father[NMAX], inQueue[NMAX], BellmanFordDistance[NMAX], DijkstraDistance[NMAX], Distance[NMAX];
queue < int > q;
priority_queue < pair < int, int > > Q;
vector < int > Edges[NMAX];
void SetVector(int a[], int value)
{
for(int i = 1; i <= N; i++)
a[i] = value;
}
void BellmanFord()
{
int X;
SetVector(BellmanFordDistance, INF);
BellmanFordDistance[Source] = 0;
q.push(Source);
inQueue[Source] = 1;
while(!q.empty())
{
X = q.front();
q.pop();
inQueue[X] = 0;
for(int &it : Edges[X])
if(Graph[X][it] && BellmanFordDistance[X] + Cost[X][it] < BellmanFordDistance[it])
{
BellmanFordDistance[it] = BellmanFordDistance[X] + Cost[X][it];
if(!inQueue[it])
inQueue[it] = 1, q.push(it);
}
}
}
int Dijkstra()
{
int Bottleneck;
pair < int, int > X;
SetVector(DijkstraDistance, INF);
Distance[Source] = 0;
DijkstraDistance[Source] = 0;
Father[Source] = -1;
Q.push({0, Source});
while(!Q.empty())
{
X = Q.top();
Q.pop();
if(DijkstraDistance[X.second] == -X.first)
for(int &it : Edges[X.second])
if(Graph[X.second][it] > 0 && DijkstraDistance[X.second] + Cost[X.second][it] + BellmanFordDistance[X.second] - BellmanFordDistance[it] < DijkstraDistance[it])
{
DijkstraDistance[it] = DijkstraDistance[X.second] + Cost[X.second][it] + BellmanFordDistance[X.second] - BellmanFordDistance[it];
Distance[it] = Distance[X.second] + Cost[X.second][it];
Father[it] = X.second;
Q.push({-DijkstraDistance[it], it});
}
}
memcpy(BellmanFordDistance, Distance, sizeof(int) * (N + 5));
if(DijkstraDistance[Destination] == INF)
return 0;
Bottleneck = Graph[Father[Destination]][Destination];
for(int x = Destination; Father[x] != -1; x = Father[x])
Bottleneck = min(Bottleneck, Graph[Father[x]][x]);
for(int x = Destination; x != Source; x = Father[x])
Graph[Father[x]][x] -= Bottleneck, Graph[x][Father[x]] += Bottleneck;
TotalFlow += Bottleneck * Distance[Destination];
return 1;
}
int main()
{
int x, y, c, w;
in >> N >> M >> Source >> Destination;
for(int i = 1; i <= M; i++)
{
in >> x >> y >> c >> w;
Edges[x].push_back(y);
Edges[y].push_back(x);
Graph[x][y] = c;
Cost[x][y] = w;
Cost[y][x] = -w;
}
BellmanFord();
while (Dijkstra());
out << TotalFlow;
return 0;
}