Pagini recente » Cod sursa (job #246290) | Cod sursa (job #1863761) | Cod sursa (job #3141283) | Cod sursa (job #2396526) | Cod sursa (job #2962459)
#include <fstream>
#include <queue>
using namespace std;
const int maxN = 1001;
const int infi = 1 << 30;
struct Muchie {
int src, dest;
int flx, cap;
int cost;
Muchie (int _src = 0, int _dest = 0, int _flx = 0, int _cap = 0, int _cost = 0):
src(_src), dest(_dest), flx(_flx), cap(_cap), cost(_cost) { }
} father[maxN];
vector<Muchie> G[maxN];
int cost[maxN];
bool viz[maxN];
bool bfs(int N) {
for (int i = 1; i <= N; i ++) {
cost[i] = infi;
father[i] = Muchie();
}
queue<int> q;
cost[1] = 0; q.push(1);
while(!q.empty()) {
int top = q.front(); q.pop();
for (auto it: G[top]) {
if (cost[top] + 1 < cost[it.dest] && it.flx < it.cap) {
cost[it.dest] = cost[top] + 1;
father[it.dest] = it;
q.push(it.dest);
}
}
}
return cost[N] != infi;
}
void dfs(int src) {
viz[src] = true;
for (auto it: G[src])
if (it.cap - it.flx > 0 && !viz[it.dest])
dfs(it.dest);
}
int bellman_dist[maxN], dijsktra_dist[maxN];
bool dijkstra(int N, int S, int D) {
for (int i = 0; i <= N; i ++) {
cost[i] = infi;
father[i] = Muchie();
}
priority_queue< pair<int, int> > q;
cost[S] = 0; q.push(make_pair(0, S));
while(!q.empty()) {
int top = q.top().second, c = -q.top().first; q.pop();
if (cost[top] != c)
continue;
for (auto it: G[top]) {
int dist = cost[top] + it.cost;
dist = dist + bellman_dist[top] - bellman_dist[it.dest];
if (dist < cost[it.dest] && it.flx < it.cap) {
cost[it.dest] = dist;
dijsktra_dist[it.dest] = dijsktra_dist[top] + it.cost;
father[it.dest] = it;
q.push(make_pair(-cost[it.dest], it.dest));
}
}
}
for (int i = 1; i <= N; i ++)
bellman_dist[i] = dijsktra_dist[i];
return cost[D] != infi;
}
int main() {
ifstream in("fmcm.in");
ofstream out("fmcm.out");
int N, M, S, D;
in >> N >> M >> S >> D;
for (int i = 1; i <= M; i ++) {
int src, dest, cap, cost;
in >> src >> dest >> cap >> cost;
G[src].push_back(Muchie(src, dest, 0, cap, cost));
G[dest].push_back(Muchie(dest, src, 0, 0, -cost));
}
for (int i = 0; i <= N; i ++)
bellman_dist[i] = infi;
queue<int> q;
bellman_dist[S] = 0; q.push(S);
viz[S] = true;
while(!q.empty()) {
int top = q.front(); q.pop();
viz[top] = false;
for (auto it: G[top]) {
if (it.cap > 0 && bellman_dist[top] + it.cost < bellman_dist[it.dest]) {
bellman_dist[it.dest] = bellman_dist[top] + it.cost;
if(!viz[it.dest]) {
q.push(it.dest);
viz[it.dest] = true;
}
}
}
}
vector<Muchie> drum;
int flx_max = 0;
while(dijkstra(N, S, D)) {
int flux = infi, cost_flux = 0;
int x = D;
while (x != S) {
flux = min(flux, father[x].cap - father[x].flx);
cost_flux += father[x].cost;
x = father[x].src;
}
flx_max += flux * cost_flux;
x = D;
while (x != S) {
for (auto &it: G[father[x].src])
if (it.dest == x) {
it.flx += flux;
break;
}
for (auto &it: G[father[x].dest])
if (it.dest == father[x].src) {
it.flx -= flux;
break;
}
x = father[x].src;
}
}
out << flx_max << "\n";
return 0;
}