제출 #1124935

#제출 시각아이디문제언어결과실행 시간메모리
1124935seiryuu학교 설립 (IZhO13_school)C++20
35 / 100
2098 ms86928 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") using namespace std; typedef long long ll; const ll INF = 1e18; inline int readInt(){ char c; while (c = getchar(), c != '-' && (c < '0' || c > '9')); bool sign = (c == '-'); if (sign) c = getchar(); int n = c - '0'; while(c = getchar(), c >= '0' && c <= '9') n = 10 * n + c - '0'; return ( (!sign) ? n : -n ) ; } struct Edge { int to, rev; ll cap, cost; }; void add_edge(vector<vector<Edge>> &g, int u, int v, ll cap, ll cost) { Edge a = {v, (int)g[v].size(), cap, cost}; Edge b = {u, (int)g[u].size(), 0, -cost}; g[u].push_back(a); g[v].push_back(b); } pair<ll, ll> min_cost_max_flow(vector<vector<Edge>> &g, int src, int snk) { int n = g.size(); ll flow = 0, cost = 0; vector<ll> pot(n, 0); while (true) { priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq; vector<ll> dist(n, INF); vector<int> pv(n, -1), pe(n, -1); dist[src] = 0; pq.emplace(0, src); while (!pq.empty()) { auto [d, u] = pq.top(); pq.pop(); if (d > dist[u]) continue; for (int i = 0; i < g[u].size(); i++) { Edge &e = g[u][i]; if (e.cap > 0 && dist[e.to] > dist[u] + e.cost + pot[u] - pot[e.to]) { dist[e.to] = dist[u] + e.cost + pot[u] - pot[e.to]; pv[e.to] = u; pe[e.to] = i; pq.emplace(dist[e.to], e.to); } } } if (dist[snk] == INF) break; for (int i = 0; i < n; i++) if (dist[i] < INF) pot[i] += dist[i]; ll add_flow = INF; for (int v = snk; v != src; v = pv[v]) { int u = pv[v], idx = pe[v]; add_flow = min(add_flow, g[u][idx].cap); } flow += add_flow; cost += add_flow * pot[snk]; for (int v = snk; v != src; v = pv[v]) { int u = pv[v], idx = pe[v]; g[u][idx].cap -= add_flow; g[v][g[u][idx].rev].cap += add_flow; } } return {flow, cost}; } int main() { ios::sync_with_stdio(false); cin.tie(NULL); int n, m, s; n = readInt(), m = readInt(), s = readInt(); int src = 0, mus = 1, spr = 2, snk = 3 + n, total = 4 + n; vector<vector<Edge>> g(total); vector<pair<int, int>> c(n); for (int i = 0; i < n; i++){ c[i].first = readInt(); c[i].second = readInt(); } add_edge(g, src, mus, m, 0); add_edge(g, src, spr, s, 0); for (int i = 0; i < n; i++) { int city = 3 + i; add_edge(g, mus, city, 1, -(ll)c[i].first); add_edge(g, spr, city, 1, -(ll)c[i].second); } for (int i = 0; i < n; i++) { int city = 3 + i; add_edge(g, city, snk, 1, 0); } auto res = min_cost_max_flow(g, src, snk); if (res.first != (ll)(m + s)) { cout << "0"; return 0; } cout << -res.second; }
#Verdict Execution timeMemoryGrader output
Fetching results...