This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub gtnao/algorithm
#define PROBLEM \ "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/5/GRL_6_B" #include <bits/stdc++.h> using namespace std; #include "../../src/flow/primal_dual.hpp" int main() { int V, E, F; cin >> V >> E >> F; PrimalDual<int, int> pd(V); for (int i = 0; i < E; i++) { int u, v, c, d; cin >> u >> v >> c >> d; pd.add_edge(u, v, c, d); } cout << pd.min_cost_flow(0, V - 1, F) << endl; return 0; }
#line 1 "test/aoj/grl_6_b.test.cpp" #define PROBLEM \ "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/5/GRL_6_B" #include <bits/stdc++.h> using namespace std; #line 2 "src/flow/primal_dual.hpp" #line 4 "src/flow/primal_dual.hpp" using namespace std; template <typename FlowT, typename CostT> struct PrimalDual { private: struct Edge { int from; int to; FlowT cap; CostT cost; int rev; bool is_rev; }; CostT INF = numeric_limits<CostT>::max(); int n; vector<vector<Edge>> graph; using Pi = pair<CostT, int>; priority_queue<Pi, vector<Pi>, greater<Pi>> que; vector<CostT> potential, min_cost; vector<int> prevv, preve; public: PrimalDual(int n) : n(n), graph(n), potential(n), min_cost(n), prevv(n, -1), preve(n, -1) {} void add_edge(int from, int to, FlowT cap, CostT cost) { graph[from].emplace_back( (Edge){from, to, cap, cost, (int)graph[to].size(), false}); graph[to].emplace_back( (Edge){to, from, 0, -cost, (int)graph[from].size() - 1, true}); } CostT min_cost_flow(int s, int t, FlowT f) { CostT ret = 0; while (f > 0) { min_cost.assign(n, INF); que.emplace(0, s); min_cost[s] = 0; while (!que.empty()) { Pi p = que.top(); que.pop(); if (min_cost[p.second] < p.first) continue; for (int i = 0; i < (int)graph[p.second].size(); ++i) { Edge &e = graph[p.second][i]; CostT next_cost = min_cost[p.second] + e.cost + potential[p.second] - potential[e.to]; if (e.cap > 0 && min_cost[e.to] > next_cost) { min_cost[e.to] = next_cost; prevv[e.to] = p.second; preve[e.to] = i; que.emplace(min_cost[e.to], e.to); } } } if (min_cost[t] == INF) return -1; for (int v = 0; v < n; ++v) { potential[v] += min_cost[v]; } FlowT add_flow = f; for (int v = t; v != s; v = prevv[v]) { add_flow = min(add_flow, graph[prevv[v]][preve[v]].cap); } f -= add_flow; ret += add_flow * potential[t]; for (int v = t; v != s; v = prevv[v]) { Edge &e = graph[prevv[v]][preve[v]]; e.cap -= add_flow; graph[v][e.rev].cap += add_flow; } } return ret; } }; #line 8 "test/aoj/grl_6_b.test.cpp" int main() { int V, E, F; cin >> V >> E >> F; PrimalDual<int, int> pd(V); for (int i = 0; i < E; i++) { int u, v, c, d; cin >> u >> v >> c >> d; pd.add_edge(u, v, c, d); } cout << pd.min_cost_flow(0, V - 1, F) << endl; return 0; }