Pagini recente » Cod sursa (job #1205589) | Cod sursa (job #2171807) | Cod sursa (job #2322049) | Cod sursa (job #1657836) | Cod sursa (job #2725489)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int INF = 1e9;
const int N = 355;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
int n, m, source, sink, fMax, cMax;
int cap[N][N], flow[N][N], costMatrix[N][N];
vector<int> g[N];
vector<int> t, realDist, newRealDist, positiveDist;
vector<bool> vis;
void BellmanFordCoada(int s)
{
vector<bool> inCoada(n + 1, false);
queue<int> q;
realDist.assign(n + 1, INF);
t.assign(n + 1, 0);
q.push(s);
inCoada[s] = true;
realDist[s] = 0;
while(!q.empty())
{
int x = q.front();
q.pop();
inCoada[x] = false;
for(int y : g[x])
{
int cost = costMatrix[x][y];
if(flow[x][y] < cap[x][y] && realDist[x] + cost < realDist[y])
{
realDist[y] = realDist[x] + cost;
t[y] = x;
if(!inCoada[y])
{
q.push(y);
inCoada[y] = true;
}
}
}
}
}
void Dijkstra(int s)
{
positiveDist.assign(n + 1, INF);
newRealDist.assign(n + 1, INF);
vis.assign(n + 1, false);
t.assign(n + 1, 0);
priority_queue<pair<int, int>> heap;
positiveDist[s] = newRealDist[s] = 0;
heap.push({0, s});
while(!heap.empty())
{
int x = heap.top().second;
int cost = -heap.top().first;
heap.pop();
if(vis[x])
continue;
vis[x] = true;
for(int y : g[x])
{
int positiveCost = realDist[x] + costMatrix[x][y] - realDist[y];
if(!vis[y] && flow[x][y] != cap[x][y] && positiveDist[x] + positiveCost < positiveDist[y])
{
heap.push({-(positiveDist[x] + positiveCost), y});
positiveDist[y] = positiveDist[x] + positiveCost;
newRealDist[y] = newRealDist[x] + costMatrix[x][y];
t[y] = x;
}
}
}
realDist = newRealDist;
}
int maxFlowMinCost()
{
// for computing initial distances
BellmanFordCoada(source);
fMax = 0;
cMax = 0;
do
{
Dijkstra(source);
if(realDist[sink] == INF)
break;
int fmin = 1 << 30;
for(int node = sink; node != source; node = t[node])
{
fmin = min(fmin, cap[t[node]][node] - flow[t[node]][node]);
}
if(fmin == 0)
continue;
fMax += fmin;
cMax += realDist[sink] * fmin;
for(int node = sink; node != source; node = t[node])
{
flow[t[node]][node] += fmin;
flow[node][t[node]] -= fmin;
}
} while(realDist[sink] != INF);
return cMax;
}
int main()
{
fin >> n >> m >> source >> sink;
for(int i = 0; i < m; i++)
{
int x, y, c, cost;
fin >> x >> y >> c >> cost;
g[x].push_back(y);
g[y].push_back(x);
cap[x][y] = c;
costMatrix[x][y] = cost;
costMatrix[y][x] = -cost;
}
fout << maxFlowMinCost() << '\n';
return 0;
}