Pagini recente » Cod sursa (job #790346) | Cod sursa (job #2692701) | Cod sursa (job #905547) | Cod sursa (job #2708411) | Cod sursa (job #2085523)
#include <bits/stdc++.h>
using namespace std;
const int INF = (1LL << 31) - 1;
const int MAX_N = 350;
typedef pair<int, int> p;
vector<int>G[MAX_N + 5];
int nrv[MAX_N + 5];
bool inc[MAX_N + 5];
int dist[MAX_N + 5];
int from[MAX_N + 5];
bool muchie[MAX_N + 5][MAX_N + 5];
int cr[MAX_N + 5][MAX_N + 5];
int cost[MAX_N + 5][MAX_N + 5];
int cost1[MAX_N + 5][MAX_N + 5];
int dijkstra(int s, int d, int n) {
for (int i = 1; i <= n; ++i)
dist[i] = INF;
priority_queue<p>pq;
pair<int, int>st = make_pair(0, s);
pq.push(st);
dist[s] = 0;
while (!pq.empty() && dist[d] == INF) {
p aux = pq.top();
pq.pop();
for (auto it:G[aux.second]) {
if (dist[it] == INF && cr[aux.second][it] > 0) {
dist[it] = cost1[aux.second][it] + aux.first;
from[it] = aux.second;
p aux1 = make_pair(dist[it], it);
pq.push(aux1);
}
}
}
return dist[d];
}
int fmcm(int s, int d, int n) {
int ans = 0, dm;
dm = dijkstra(s, d, n);
while (dm != INF) {
int aux = INF;
int node = d;
while (node != s) {
aux = min(aux, cr[from[node]][node]);
node = from[node];
}
node = d;
dm = 0;
while (node != s) {
dm += cost[from[node]][node];
cr[from[node]][node] -= aux;
cr[node][from[node]] += aux;
node = from[node];
}
ans += dm * aux;
dm = dijkstra(s, d, n);
}
return ans;
}
int main() {
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
int n, m, s, d;
scanf("%d%d%d%d", &n, &m, &s, &d);
for (int i = 1; i <= m; ++i) {
int u, v, c, cst;
scanf("%d%d%d%d", &u, &v, &c, &cst);
G[u].push_back(v);
G[v].push_back(u);
cr[u][v] = c;
muchie[u][v] = 1;
cost[u][v] = cst;
cost[v][u] = -cst;
}
for (int i = 1; i <= n; ++i) {
dist[i] = INF;
nrv[i] = 0;
inc[i] = 0;
}
inc[s] = 1;
from[s] = s;
nrv[s] = 1;
dist[s] = 0;
queue<int>q;
q.push(s);
while (!q.empty() && nrv[q.front()] < n) {
int node = q.front();
q.pop();
inc[node] = 0;
for (auto it:G[node]) {
if (cr[node][it] > 0 && dist[node] + cost[node][it] < dist[it]) {
from[it] = node;
dist[it] = dist[node] + cost[node][it];
if (inc[it] == 0) {
inc[it] = 1;
q.push(it);
nrv[it]++;
}
}
}
}
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (muchie[i][j]) {
cost1[i][j] = cost[i][j] + dist[i] - dist[j];
cost1[j][i] = -cost1[i][j];
}
printf("%d\n", fmcm(s, d, n));
return 0;
}