This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub fffelix-huang/CP-stuff
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_B" #include <iostream> #include "../../../library/flow/mincostflow.hpp" using namespace std; using namespace felix; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m, k; cin >> n >> m >> k; MCMF<int, int> f(n); for(int i = 0; i < m; i++) { int u, v, cap, cost; cin >> u >> v >> cap >> cost; f.add_edge(u, v, cap, cost); } auto [cap, cost] = f.flow(0, n - 1, k); if(cap < k) { cout << "-1\n"; } else { cout << cost << "\n"; } return 0; }
#line 1 "test/flow/mincostflow/aoj-grl-Minimum-Cost-Flow.test.cpp" #define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_B" #include <iostream> #line 2 "library/flow/mincostflow.hpp" #include <vector> #include <queue> #include <cassert> #include <limits> namespace felix { template<class Cap_t, class Cost_t> struct MCMF { public: struct edge_t { int from; int to; Cap_t cap; Cost_t cost; edge_t(int u, int v, Cap_t _cap, Cost_t _cost) : from(u), to(v), cap(_cap), cost(_cost) {} }; static constexpr Cap_t CAP_INF = std::numeric_limits<Cap_t>::max(); static constexpr Cost_t COST_INF = std::numeric_limits<Cost_t>::max(); int n; std::vector<edge_t> edges; std::vector<std::vector<int>> g; std::vector<Cost_t> d; std::vector<bool> in_queue; std::vector<int> previous_edge; MCMF() : n(0) {} explicit MCMF(int _n) : n(_n), g(_n), d(_n), in_queue(_n), previous_edge(_n) {} void add_edge(int u, int v, Cap_t cap, Cost_t cost) { assert(0 <= u && u < n); assert(0 <= v && v < n); g[u].push_back(edges.size()); edges.emplace_back(u, v, cap, cost); g[v].push_back(edges.size()); edges.emplace_back(v, u, 0, -cost); } bool spfa(int s, int t) { bool found = false; std::fill(d.begin(), d.end(), COST_INF); d[s] = 0; in_queue[s] = true; std::queue<int> que; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); if(u == t) { found = true; } in_queue[u] = false; for(auto& id : g[u]) { const edge_t& e = edges[id]; if(e.cap > 0 && d[u] + e.cost < d[e.to]) { d[e.to] = d[u] + e.cost; previous_edge[e.to] = id; if(!in_queue[e.to]) { que.push(e.to); in_queue[e.to] = true; } } } } return found; } std::pair<Cap_t, Cost_t> flow(int s, int t, Cap_t f = CAP_INF) { assert(0 <= s && s < n); assert(0 <= t && t < n); Cap_t cap = 0; Cost_t cost = 0; while(f > 0 && spfa(s, t)) { Cap_t send = f; int u = t; while(u != s) { const edge_t& e = edges[previous_edge[u]]; send = std::min(send, e.cap); u = e.from; } u = t; while(u != s) { edge_t& e = edges[previous_edge[u]]; e.cap -= send; edge_t& b = edges[previous_edge[u] ^ 1]; b.cap += send; u = e.from; } cap += send; f -= send; cost += send * d[t]; } return std::make_pair(cap, cost); } }; } // namespace felix #line 5 "test/flow/mincostflow/aoj-grl-Minimum-Cost-Flow.test.cpp" using namespace std; using namespace felix; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m, k; cin >> n >> m >> k; MCMF<int, int> f(n); for(int i = 0; i < m; i++) { int u, v, cap, cost; cin >> u >> v >> cap >> cost; f.add_edge(u, v, cap, cost); } auto [cap, cost] = f.flow(0, n - 1, k); if(cap < k) { cout << "-1\n"; } else { cout << cost << "\n"; } return 0; }