Submission #1219790

#TimeUsernameProblemLanguageResultExecution timeMemory
1219790AdnanboiTug of War (BOI15_tug)C++20
0 / 100
3094 ms6736 KiB
#include <bits/stdc++.h> using namespace std; const int INF = 1e9; struct Edge { int to, rev, cap, cost; Edge(int t, int r, int ca, int co): to(t), rev(r), cap(ca), cost(co) {} }; class MinCostMaxFlow { public: int n; vector<vector<Edge>> g; vector<int> dist, inqueue; vector<int> prev, preve; MinCostMaxFlow(int _n): n(_n), g(_n), prev(_n), preve(_n), dist(_n), inqueue(_n) {} void addEdge(int from, int to, int cap, int cost) { Edge e1(to, g[to].size(), cap, cost); Edge e2(from, g[from].size(), 0, -cost); g[from].push_back(e1); g[to].push_back(e2); } pair<int, int> flow(int s, int t, int maxf) { int flow = 0, cost = 0; while (true) { fill(dist.begin(), dist.end(), INF); fill(inqueue.begin(), inqueue.end(), false); queue<int> q; dist[s] = 0; q.push(s); inqueue[s] = true; while (!q.empty()) { int v = q.front(); q.pop(); inqueue[v] = false; for (int i = 0; i < g[v].size(); ++i) { Edge &e = g[v][i]; if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) { dist[e.to] = dist[v] + e.cost; prev[e.to] = v; preve[e.to] = i; if (!inqueue[e.to]) { q.push(e.to); inqueue[e.to] = true; } } } } if (dist[t] == INF) break; int d = maxf - flow; for (int v = t; v != s; v = prev[v]) d = min(d, g[prev[v]][preve[v]].cap); flow += d; cost += d * dist[t]; for (int v = t; v != s; v = prev[v]) { Edge &e = g[prev[v]][preve[v]]; e.cap -= d; g[v][e.rev].cap += d; } } return {flow, cost}; } }; int main() { int N, K; cin >> N >> K; int totalStrength = 0; vector<pair<int, int>> lr(2*N); vector<int> s(2*N); for (int i = 0; i < 2*N; ++i) { int l, r, si; cin >> l >> r >> si; lr[i] = {l, r}; s[i] = si; totalStrength += si; } const int SRC = 2*N + 2*N; const int SINK = SRC + 1; const int TOTAL = SINK + 1; MinCostMaxFlow mcmf(TOTAL); // Source -> Players for (int i = 0; i < 2*N; ++i) mcmf.addEdge(SRC, i, 1, 0); // Players -> Left/Right Positions for (int i = 0; i < 2*N; ++i) { auto [l, r] = lr[i]; mcmf.addEdge(i, 2*N + (l-1), 1, s[i]); // left team adds strength mcmf.addEdge(i, 2*N + N + (r-1), 1, -s[i]); // right team subtracts strength } // Positions -> Sink for (int i = 0; i < N; ++i) mcmf.addEdge(2*N + i, SINK, 1, 0); for (int i = 0; i < N; ++i) mcmf.addEdge(2*N + N + i, SINK, 1, 0); auto [flow, cost] = mcmf.flow(SRC, SINK, 2*N); if (flow != 2*N) { cout << "NO\n"; return 0; } int sumLeft = (totalStrength + cost) / 2; int sumRight = totalStrength - sumLeft; if (abs(sumLeft - sumRight) <= K) cout << "YES\n"; else cout << "NO\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...