Pagini recente » Cod sursa (job #258017) | Cod sursa (job #1975267) | Cod sursa (job #2155834) | Cod sursa (job #2739242) | Cod sursa (job #3233275)
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
#include <fstream>
using namespace std;
const int INF = INT_MAX;
struct Edge {
int to, capacity, cost, flow, reverse_index;
};
class MinCostMaxFlow {
public:
MinCostMaxFlow(int n) : graph(n), potential(n, 0), dist(n), prev_vertex(n), prev_edge(n) {}
void addEdge(int u, int v, int capacity, int cost) {
graph[u].emplace_back(Edge{v, capacity, cost, 0, (int) graph[v].size()});
graph[v].emplace_back(Edge{u, 0, -cost, 0, (int) graph[u].size() - 1});
}
pair<int, int> getMinCostMaxFlow(int s, int t) {
int flow = 0, cost = 0;
while (bellmanFord(s, t)) {
int pushed_flow = INF;
for (int v = t; v != s; v = prev_vertex[v]) {
pushed_flow = min(pushed_flow, graph[prev_vertex[v]][prev_edge[v]].capacity - graph[prev_vertex[v]][prev_edge[v]].flow);
}
for (int v = t; v != s; v = prev_vertex[v]) {
graph[prev_vertex[v]][prev_edge[v]].flow += pushed_flow;
graph[v][graph[prev_vertex[v]][prev_edge[v]].reverse_index].flow -= pushed_flow;
cost += pushed_flow * graph[prev_vertex[v]][prev_edge[v]].cost;
}
flow += pushed_flow;
}
return {flow, cost};
}
private:
vector<vector<Edge>> graph;
vector<int> potential, dist, prev_vertex, prev_edge;
bool bellmanFord(int s, int t) {
fill(dist.begin(), dist.end(), INF);
dist[s] = 0;
bool improved;
for (int i = 0; i < graph.size(); ++i) {
improved = false;
for (int u = 0; u < graph.size(); ++u) {
for (int j = 0; j < graph[u].size(); ++j) {
Edge &e = graph[u][j];
if (e.capacity > e.flow && dist[e.to] > dist[u] + e.cost) {
dist[e.to] = dist[u] + e.cost;
prev_vertex[e.to] = u;
prev_edge[e.to] = j;
improved = true;
}
}
}
if (!improved) break;
}
return dist[t] != INF;
}
};
int main() {
ifstream infile("fmcm.in");
ofstream outfile("fmcm.out");
int N, M, S, D;
infile >> N >> M >> S >> D;
MinCostMaxFlow mcmf(N);
for (int i = 0; i < M; ++i) {
int x, y, c, z;
infile >> x >> y >> c >> z;
mcmf.addEdge(x - 1, y - 1, c, z);
}
auto result = mcmf.getMinCostMaxFlow(S - 1, D - 1);
outfile << result.second << endl;
infile.close();
outfile.close();
return 0;
}