Submission #1268060

#TimeUsernameProblemLanguageResultExecution timeMemory
1268060rtriTug of War (BOI15_tug)C++20
0 / 100
38 ms5600 KiB
#include <bits/stdc++.h> using namespace std; typedef long long int ll; int n, k; vector<int> used; vector<pair<int, int>> positions; vector<ll> strengths; vector<unordered_set<int>> lefts, rights; vector<bool> lfilled, rfilled; int get_not(unordered_set<int> as, int b) { if (as.size() != 2) assert(false); for (auto a : as) if (a != b) return a; assert(false); } ll cycle(int i, bool is_left, int start_idx = -1) { if (start_idx == i) return 0; if (start_idx == -1) start_idx = i; used[i] = start_idx; if (is_left) { int forced = get_not(lefts[positions[i].first], i); return strengths[i] + cycle(forced, !is_left, start_idx); } else { int forced = get_not(rights[positions[i].second], i); return cycle(forced, !is_left, start_idx); } } int forced_fill(int i) { if (used[i] != -1) { cout << "NO" << endl; exit(0); } auto [currl, currr] = positions[i]; if (lfilled[currl] && rfilled[currr]) { cout << "NO" << endl; exit(0); } else if (lfilled[currl]) { rfilled[currr] = 1; used[i] = 1; lefts[currl].erase(i); rights[currr].erase(i); return 0; } else if (rfilled[currr]) { lfilled[currl] = 1; used[i] = 1; lefts[currl].erase(i); rights[currr].erase(i); return strengths[i]; } else { if (lefts[currl].size() == 1 && rights[currr].size() == 1) { cout << "NO" << endl; exit(0); } else if (lefts[currl].size() == 1) { lfilled[currl] = 1; used[i] = 1; lefts[currl].erase(i); rights[currr].erase(i); if (rights[currr].size() == 1) return strengths[i] + forced_fill(*rights[currr].begin()); } else if (rights[currl].size() == 1) { rfilled[currr] = 1; used[i] = 1; lefts[currl].erase(i); rights[currr].erase(i); if (lefts[currl].size() == 1) return forced_fill(*lefts[currl].begin()); } } return 0; } int main() { cin >> n >> k; ll total_strength = 0; positions.resize(2 * n); strengths.resize(2 * n); lefts.resize(n); rights.resize(n); lfilled.resize(n); rfilled.resize(n); for (int i = 0; i < n * 2; i++) { int l, r, s; cin >> l >> r >> s; l--; r--; positions[i] = {l, r}; strengths[i] = s; lefts[l].insert(i); rights[r].insert(i); total_strength += s; } ll base = 0; used.resize(2 * n, -1); for (int i = 0; i < 2 * n; i++) { if (used[i] != -1) continue; base += forced_fill(i); } for (int i = 0; i < n; i++) { int ls = lefts[i].size(), rs = rights[i].size(); if ((!lfilled[i] && ls != 2) || (!rfilled[i] && rs != 2)) { cout << "NO" << endl; return 0; } } vector<ll> knapsack; for (int i = 0; i < 2 * n; i++) { if (used[i] != -1) continue; int r = cycle(i, false); int l = cycle(i, true); base += min(r, l); knapsack.push_back(max(r, l) - min(r, l)); } cerr << "TOTAL " << total_strength << endl; cerr << "BASE " << base << endl; for (int i = 0; i < knapsack.size(); i++) cerr << knapsack[i] << " "; cerr << endl; bitset<50000> reach; reach[base] = 1; for (int elem : knapsack) reach |= reach << elem; for (int i = (total_strength - k + 1) / 2; i <= (total_strength + k) / 2; i++) { assert(abs(i - (total_strength - i)) <= k); if (reach[i]) { cout << "YES" << endl; return 0; } } cout << "NO" << endl; 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...