Pagini recente » Cod sursa (job #1916874) | Cod sursa (job #2271339) | Cod sursa (job #2685403)
#include <iostream>
#include <fstream>
#include <queue>
#include <set>
#include <algorithm>
#include <stack>
#include <vector>
#include <iomanip>
#include <cstdio>
#define INF (int)2e9 + 7
#define MAXN (int)4e2 + 5
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
int N, M, source, dest;
vector<int> G[MAXN];
int flow[MAXN][MAXN];
int capacity[MAXN][MAXN];
int cost[MAXN][MAXN];
bool visited[MAXN];
int D[MAXN];
int dad[MAXN];
int oldD[MAXN];
int newD[MAXN];
void bellman_ford() {
for (int i = 1; i <= N; ++i)
oldD[i] = INF;
queue<int> Q;
visited[source] = true;
oldD[source] = 0;
Q.push(source);
while (Q.size() > 0) {
int u = Q.front();
Q.pop();
visited[u] = true;
for (int v : G[u]) {
if (flow[u][v] < capacity[u][v]) {
if (oldD[v] > oldD[u] + cost[u][v]) {
oldD[v] = oldD[u] + cost[u][v];
if (visited[v] == false) {
visited[v] = true;
Q.push(v);
}
}
}
}
}
}
bool Dijkstra() {
for (int i = 1; i <= N; ++i) {
D[i] = INF;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> PQ;
PQ.push(make_pair(0, source));
visited[source] = true;
D[source] = newD[source] = 0;
while (PQ.size() > 0) {
int u = PQ.top().second;
int c = PQ.top().first;
PQ.pop();
if (D[u] != c)
continue;
for (int v : G[u]) {
if (flow[u][v] < capacity[u][v]) {
if (D[v] > D[u] + cost[u][v] + oldD[u] - oldD[v]) {
D[v] = D[u] + cost[u][v] + oldD[u] - oldD[v];
newD[v] = newD[u] + cost[u][v];
dad[v] = u;
PQ.push(make_pair(D[v], v));
}
}
}
}
for (int i = 1; i <= N; ++i) {
oldD[i] = newD[i];
}
return (D[dest] < INF);
}
int main() {
int u, v, cst, cap, maxFlow = 0, minFlow;
fin >> N >> M >> source >> dest;
for (int i = 0; i < M; ++i) {
fin >> u >> v >> cap >> cst;
capacity[u][v] = cap;
cost[u][v] = cst;
cost[v][u] = -cst;
G[u].push_back(v);
G[v].push_back(u);
}
bellman_ford();
while (Dijkstra()) {
minFlow = INF;
for (int i = dest; i != source; i = dad[i])
minFlow = min(minFlow, capacity[dad[i]][i] - flow[dad[i]][i]);
for (int i = dest; i != source; i = dad[i]) {
flow[dad[i]][i] += minFlow;
flow[i][dad[i]] -= minFlow;
}
maxFlow += minFlow * newD[dest];
}
fout << maxFlow << "\n";
return 0;
}