Pagini recente » Cod sursa (job #2838038) | Cod sursa (job #195164) | Cod sursa (job #969777) | Cod sursa (job #2092629) | Cod sursa (job #2658427)
#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>
#include <queue>
using namespace std;
#define INF 1<<31 - 1
#define MAXN 352
int cap[MAXN][MAXN];
int cost[MAXN][MAXN];
vector<vector<int>> arcs;
int parents[MAXN], d[MAXN], old_d[MAXN], real_d[MAXN];
bool in_queue[MAXN];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;
int n, flow, source, dest;
void bellmanford() {
memset(old_d, 0x3f, sizeof(old_d));
old_d[source] = 0;
in_queue[source] = 1;
int next_node, current_node;
queue<int> q;
q.push(source);
while(q.size()) {
current_node = q.front();
q.pop();
for(int i=0; i<arcs[current_node].size(); ++i) {
next_node = arcs[current_node][i];
if (cap[current_node][next_node]) {
if (old_d[current_node] + cost[current_node][next_node] < old_d[next_node]) {
old_d[next_node] = old_d[current_node] + cost[current_node][next_node];
if (! in_queue[next_node]) {
in_queue[next_node] = true;
q.push(next_node);
}
}
}
}
}
}
bool dijkstra() {
int current_node, next_node, current_cost, current_d;
memset(d, 0x3f, sizeof(d));
d[source] = 0;
real_d[source] = 0;
pq.push(pair<int, int>(d[source], source));
while( pq.size() ) {
current_node = pq.top().second;
current_cost = pq.top().first;
pq.pop();
if (d[current_node] == current_cost)
for(int i=0; i<arcs[current_node].size(); ++i)
if (cap[current_node][arcs[current_node][i]]) {
next_node = arcs[current_node][i];
current_d = d[current_node] + cost[current_node][next_node] + old_d[current_node] - old_d[next_node];
if (current_d < d[next_node]) {
d[next_node] = current_d;
real_d[next_node] = real_d[current_node] + cost[current_node][next_node];
parents[next_node] = current_node;
pq.push(pair<int, int>(d[next_node], next_node));
}
}
}
if (d[dest] == 0x3f3f3f3f)
return false;
memcpy(old_d, real_d, sizeof(real_d));
current_d = INF;
for(int i=dest; i!= source; i = parents[i])
if (cap[parents[i]][i] < current_d)
current_d = cap[parents[i]][i];
flow += current_d * real_d[dest];
for(int i=dest; i!= source; i = parents[i]) {
cap[parents[i]][i] -= current_d;
cap[i][parents[i]] += current_d;
}
return true;
}
int main() {
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
int m, a, b, c, e;
scanf("%d%d%d%d", &n, &m, &source, &dest);
arcs.resize(n+1);
for(int i=0; i<m; ++i) {
scanf("%d%d%d%d", &a, &b, &c, &e);
arcs[a].push_back(b);
arcs[b].push_back(a);
cap[a][b] += c;
cost[a][b] += e;
cost[b][a] -= e;
}
bellmanford();
while(dijkstra());
printf("%d\n", flow);
return 0;
}