Pagini recente » Diferente pentru utilizator/stargold2 intre reviziile 275 si 127 | Diferente pentru utilizator/visuianmihai intre reviziile 116 si 46 | Diferente pentru implica-te/scrie-articole intre reviziile 59 si 58 | Diferente pentru home intre reviziile 769 si 770 | Cod sursa (job #1985514)
#include <iostream>
#include <cstdio>
#include <fstream>
#include <vector>
#include <bitset>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>
#define NMAX 355
#define oo (1 << 30)
using namespace std;
int n, m, source, sink;
vector<int> G[NMAX];
int old_d[NMAX];
queue<int> Q;
bitset<NMAX> inQ;
int d[NMAX], p[NMAX], real_d[NMAX];
// struct cmp {
// bool operator()(const int &a, const int &b) {
// return d[a] > d[b];
// }
// };
// priority_queue<int, vector<int>, cmp> pq;
typedef pair<int, int> state;
priority_queue<state, vector<state>, greater<state> > pq;
int flow[NMAX][NMAX], cap[NMAX][NMAX], cost[NMAX][NMAX];
int x, y, c, z;
#define pb push_back
#define f cin
void ceplm() {
f >> n >> m >> source >> sink;
for(int i = 1; i <= m; ++i) {
f >> x >> y >> c >> z;
G[x].pb(y);
G[y].pb(x);
cap[x][y]=c;
cost[x][y] = +z;
cost[y][x] = -z;
}
}
int Bellman(int source) {
for(int i = 1; i <= n; ++i) {
old_d[i] = oo;
}
Q.push(source);
old_d[source] = 0;
inQ[source] = 1;
while (!Q.empty()) {
int node = Q.front();
Q.pop();
inQ[node] = 0;
for(auto it : G[node]) {
if (old_d[node] + cost[node][it] < old_d[it] && flow[node][it] < cap[node][it]) {
old_d[it] = old_d[node] + cost[node][it];
if (!inQ[it]) {
Q.push(it);
inQ[it] = 1;
}
}
}
}
}
bool Dijkstra(int source, int sink) {
for (int i = 1; i <= n; ++i) {
p[i] = oo;
d[i] = oo;
real_d[i] = oo;
}
pq.push( state(0, source) );
p[source] = 0;
d[source] = 0;
real_d[source] = 0;
while (!pq.empty()) {
state s = pq.top();
pq.pop();
int node = s.second;
int dist = s.first;
if (d[node] < dist) {
continue;
}
for (auto it : G[node]) {
long long d_aux = d[node] + cost[node][it] + old_d[node] - old_d[it];
if (d_aux < 1LL * d[it] && flow[node][it] < cap[node][it]) {
d[it] = d_aux;
p[it] = node;
real_d[it] = real_d[node] + cost[node][it];
pq.push( state(d[it], it) );
}
}
}
for (int i = 1; i <= n; ++i) {
old_d[i] = real_d[i];
}
return d[sink] != oo;
}
void FMCM(int source, int sink) {
int maxFlow = 0, minCost = 0;
while (Dijkstra(source, sink)) {
int minFlow = oo;
for (int node = sink; node != source; node = p[node]) {
int parent = p[node],
available_flow = cap[ parent ][ node ] - flow[ parent ][ node ];
minFlow = min(minFlow, available_flow);
}
if (minFlow > 0) {
maxFlow += minFlow;
minCost += minFlow * real_d[sink];
for (int node = sink; node != source; node = p[node]) {
int parent = p[node];
flow[ parent ][ node ] += minFlow;
flow[ node ][ parent ] -= minFlow;
}
}
}
cout << minCost << "\n";
// cout << maxFlow << "\n";
}
int main() {
assert( freopen("fmcm.in", "r", stdin) != NULL);
assert( freopen("fmcm.out", "w", stdout) != NULL) ;
ceplm();
Bellman(source);
// FMCM(source, sink);
return 0;
}