Pagini recente » Cod sursa (job #2380514) | Cod sursa (job #2180702) | Cod sursa (job #2986153) | Cod sursa (job #2202625) | Cod sursa (job #3125937)
#include <bits/stdc++.h>
#define int long long
using namespace std;
#ifdef LOCAL
ifstream in("in.in");
ofstream out("out.out");
#else
ifstream in("fmcm.in");
ofstream out("fmcm.out");
#endif
namespace MaxFlow {
struct Edge {
int to,rev,cap,cost,flow = 0;
};
const int inf = 1000000005;
int n,s,t;
vector<vector<Edge>> g;
void init(int N) {
n = N;
g.resize(n + 1);
}
void add_edge(int u, int v, int flow, int cost) {
g[u].push_back(Edge{v, (int)g[v].size(), flow, cost});
g[v].push_back(Edge{u, (int)g[u].size() - 1, 0, -cost});
}
void set_sink(int S, int T) {
s = S;
t = T;
}
int get_free(Edge x) {
return x.cap - x.flow;
}
pair<int,int> add_flow() {
vector<int> dis(n + 1, inf),from_edge(n + 1),from_node(n + 1);
priority_queue<pair<int,int>> q;
dis[s] = 0;
q.push({0,s});
while(!q.empty()) {
int node = q.top().second;
int cost = -q.top().first;
q.pop();
if (cost > dis[node]) {
continue;
}
for (auto k : g[node]) {
if (k.cap - k.flow > 0 && dis[node] + k.cost < dis[k.to]) {
dis[k.to] = dis[node] + k.cost;
from_edge[k.to] = k.rev;
q.push({-dis[k.to] , k.to});
}
}
}
if (dis[t] == inf) {
return {0,0};
}
int node = t,bottle_neck = inf;
while(node != s) {
int from = g[node][from_edge[node]].to;
int edge = g[node][from_edge[node]].rev;
bottle_neck = min(bottle_neck,get_free(g[from][edge]));
node = from;
}
int cost = 0;
node = t;
while(node != s) {
int from = g[node][from_edge[node]].to;
int edge = g[node][from_edge[node]].rev;
cost += g[from][edge].cost * bottle_neck;
g[from][edge].flow += bottle_neck;
g[node][from_edge[node]].flow -= bottle_neck;
node = from;
}
return {bottle_neck, cost};
}
pair<int,int> compute() {
int flow = 0, cost = 0;
while(true) {
auto added_flow = add_flow();
if (added_flow.first == 0) {
break;
}
flow += added_flow.first;
cost += added_flow.second;
}
return {flow , cost};
}
}
int32_t main() {
int n,m,s,d;
in >> n >> m >> s >> d;
MaxFlow :: init(n);
MaxFlow :: set_sink(s,d);
for (int i = 1; i <= m; i++) {
int u,v,cap,cost;
in >> u >> v >> cap >> cost;
MaxFlow :: add_edge(u,v,cap,cost);
}
out << MaxFlow :: compute().second << "\n";
}