Pagini recente » Cod sursa (job #2708548) | Cod sursa (job #2811027) | Cod sursa (job #3286477) | Cod sursa (job #3148033) | Cod sursa (job #3253644)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <cstring>
using namespace std;
const int MAXN = 1001;
const int INF = INT_MAX;
int N, M, S, D;
int capacity[MAXN][MAXN];
int cost[MAXN][MAXN];
int flow[MAXN][MAXN];
vector<int> adj[MAXN];
int dist[MAXN];
int potential[MAXN];
int parent[MAXN];
void bellmanFord() {
fill(dist, dist + N + 1, INF);
dist[S] = 0;
for (int i = 0; i < N - 1; ++i) {
for (int u = 1; u <= N; ++u) {
for (int v : adj[u]) {
if (capacity[u][v] - flow[u][v] > 0 && dist[u] < INF) {
dist[v] = min(dist[v], dist[u] + cost[u][v]);
}
}
}
}
for (int i = 1; i <= N; ++i) {
potential[i] = dist[i];
}
}
bool dijkstra() {
fill(dist, dist + N + 1, INF);
dist[S] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, S});
memset(parent, -1, sizeof(parent));
while (!pq.empty()) {
int d = pq.top().first;
int u = pq.top().second;
pq.pop();
if (d != dist[u]) continue;
for (int v : adj[u]) {
if (capacity[u][v] - flow[u][v] > 0) {
int new_cost = cost[u][v] + potential[u] - potential[v];
if (dist[u] + new_cost < dist[v]) {
dist[v] = dist[u] + new_cost;
parent[v] = u;
pq.push({dist[v], v});
}
}
}
}
// Update potentials
for (int i = 1; i <= N; ++i) {
if (dist[i] < INF) {
potential[i] += dist[i];
}
}
return dist[D] != INF;
}
int minCostMaxFlow() {
int totalFlow = 0;
int totalCost = 0;
bellmanFord();
while (dijkstra()) {
int pathFlow = INF;
for (int v = D; v != S; v = parent[v]) {
int u = parent[v];
pathFlow = min(pathFlow, capacity[u][v] - flow[u][v]);
}
totalFlow += pathFlow;
totalCost += pathFlow * (dist[D] - potential[S] + potential[D]);
for (int v = D; v != S; v = parent[v]) {
int u = parent[v];
flow[u][v] += pathFlow;
flow[v][u] -= pathFlow;
}
}
return totalCost;
}
int main() {
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
fin >> N >> M >> S >> D;
memset(capacity, 0, sizeof(capacity));
memset(cost, 0, sizeof(cost));
memset(flow, 0, sizeof(flow));
for (int i = 0; i < M; i++) {
int x, y, c, z;
fin >> x >> y >> c >> z;
capacity[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
adj[x].push_back(y);
adj[y].push_back(x);
}
int minCost = minCostMaxFlow();
fout << minCost << endl;
fin.close();
fout.close();
return 0;
}