Pagini recente » Cod sursa (job #2945117) | Cod sursa (job #2493448) | Statistici Ana Floares (anafloares) | Statistici Florian Vlad (FlorianVlad) | Cod sursa (job #1564076)
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#define MAXN 400
#define inf 1000000000
using namespace std;
int cost[MAXN][MAXN], oldCost[MAXN][MAXN], capac[MAXN][MAXN], flow[MAXN][MAXN];
vector<int> graf[MAXN];
int n, m, s, d, sol;
int distMin[MAXN], tat[MAXN];
void citire()
{
int x, y, c, z;
scanf("%d %d %d %d", &n, &m, &s, &d);
for (int i = 1; i <= m; i++) {
scanf("%d %d %d %d", &x, &y, &c, &z);
graf[x].push_back(y);
graf[y].push_back(x);
cost[x][y] = oldCost[x][y] = z;
cost[y][x] = oldCost[y][x] = -z;
capac[x][y] += c;
}
}
queue<int> q;
int einq[MAXN], pasi[MAXN];
void bellman(int start)
{
for (int i = 0; i <= n; i++)
distMin[i] = inf;
q.push(start);
einq[start] = 1;
distMin[start] = 0;
while (!q.empty()) {
int nod = q.front();
q.pop();
einq[nod] = 0;
for (int i = 0, t = graf[nod].size(); i < t; i++) {
int y = graf[nod][i];
if (capac[nod][y] && distMin[y] > distMin[nod] + cost[nod][y]) {
distMin[y] = distMin[nod] + cost[nod][y];
if (!einq[y]) {
q.push(y);
pasi[y]++;
einq[y] = 1;
if (pasi[y] - n > 5)
cerr << "ERROR NEGATIVE CICLE";
}
}
}
}
}
void prepare(int dist[MAXN])
{
for (int i = 1; i <= n; i++)
for (int j = 0, t = graf[i].size(); j < t; j++) {
int y = graf[i][j];
if (dist[i] == inf || dist[y] == inf) continue;
cost[i][y] = oldCost[i][y] + dist[i] - dist[y];
}
}
int best[MAXN], real[MAXN];
struct cmp
{
bool operator()(int a, int b) { return best[a] > best[b]; }
};
priority_queue<int, vector<int>, cmp> pq;
int dijkstra()
{
for (int i = 0; i <= n; i++)
best[i] = inf;
while (!q.empty()) q.pop();
for (best[s] = 0, real[s] = 0, pq.push(s); !pq.empty(); ) {
int nod = pq.top();
pq.pop();
if (nod == d)
continue ;
for (int i = 0, t = graf[nod].size(); i < t; i++) {
int y = graf[nod][i];
if (capac[nod][y]-flow[nod][y] && best[y] > best[nod] + cost[nod][y]) {
tat[y] = nod;
real[y] = real[nod] + oldCost[nod][y];
best[y] = best[nod] + cost[nod][y];
pq.push(y);
}
}
}
return best[d] != inf;
}
void solve()
{
for (;dijkstra(); prepare(real)) {
int mini = inf;
for (int last = d; last != s; last = tat[last])
mini = min(mini, capac[tat[last]][last]-flow[tat[last]][last]);
if (!mini) {
cerr << "This should not have happened";
continue;
}
for (int last = d; last != s; last = tat[last]) {
flow[tat[last]][last] += mini;
flow[last][tat[last]] -= mini;
}
sol += mini * real[d];
}
}
int main()
{
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
citire();
bellman(s);
prepare(distMin);
solve();
printf("%d", sol);
return 0;
}