Submission #283171

#TimeUsernameProblemLanguageResultExecution timeMemory
283171hoanghq2004Split the Attractions (IOI19_split)C++14
100 / 100
171 ms25240 KiB
#include <bits/stdc++.h> #define split #include <split.h> using namespace std; const int N = 100005; int n; pair <int, int> a, b, c; vector <int> C, adj[N], E[N]; int sz[N], check[N], d[N]; int times, low[N], num[N]; void dfs(int u, int p) { num[u] = low[u] = ++times; sz[u] = 1; check[u] = 1; for (auto v: adj[u]) { if (v == p) continue; if (!num[v]) { E[u].push_back(v); d[v] = d[u] + 1; dfs(v, u); sz[u] += sz[v]; low[u] = min(low[u], low[v]); if (sz[v] >= a.first) check[u] = 0; } else low[u] = min(low[u], num[v]); } } void paint(int u, int num, int cl) { queue <int> q; q.push(u); int cnt = 0; if (!C[u]) { C[u] = cl; cnt = 1; } if (cnt == num) return; while (!q.empty()) { int u = q.front(); q.pop(); for (auto v: E[u]) if (!C[v]) { ++cnt; C[v] = cl; q.push(v); if (num == cnt) return; } } } vector <int> find_split(int _n, int _a, int _b, int _c, vector <int> u, vector <int> v) { n = _n; a = {_a, 1}, b = {_b, 2}, c = {_c, 3}; if (a > b) swap(a, b); if (a > c) swap(a, c); if (b > c) swap(b, c); assert(a <= b && b <= c); int m = (int)v.size(); C = vector <int> (n, 0); for (int i = 0; i < m; i ++) { adj[v[i]].push_back(u[i]); adj[u[i]].push_back(v[i]); } dfs(0, 0); for (int u = 0; u < n; ++u) { if (check[u] && sz[u] >= a.first && n - sz[u] >= a.first) { if (sz[u] <= n - sz[u]) { paint(u, a.first, a.second); paint(0, b.first, b.second); } else { paint(u, b.first, b.second); paint(0, a.first, a.second); } for (int i = 0; i < n; ++i) if (!C[i]) C[i] = c.second; return C; } } for (int u = 0; u < n; ++u) if (check[u] && n - sz[u] < a.first) { int cnt = 0; for (auto v: E[u]) if (low[v] < num[u]) cnt += sz[v]; if (cnt + n - sz[u] < a.first) continue; C[u] = b.second; paint(0, a.first, a.second); cnt = n - sz[u]; for (auto v: E[u]) { if (low[v] < num[u] && cnt + sz[v] <= a.first) { paint(v, a.first, a.second); cnt += sz[v]; if (cnt == a.first) break; else continue; } if (low[v] < num[u] && cnt + sz[v] > a.first) { int pivot = num[u]; // cout << low[v] << " " << pivot << "\n"; queue <int> q; vector <int> backward; q.push(v); while (!q.empty()) { int u = q.front(); q.pop(); int ok = 0; for (auto v: E[u]) { if (low[v] < pivot) { ok = 1; q.push(v); } } if (!ok) backward.push_back(u); } // cout << backward.size() << "\n"; // cout << backward[0] << ' '<< v << "\n"; for (auto root: backward) { q.push(root); while (!q.empty()) { int u = q.front(); q.pop(); ++cnt; C[u] = a.second; if (cnt == a.first) goto label; // assert(cnt < a.first); for (auto v: E[u]) q.push(v); } } q.push(v); stack <int> stk; while (!q.empty()) { int u = q.front(); q.pop(); stk.push(u); for (auto v: E[u]) if (!C[v]) q.push(v); } while (!stk.empty()) { int u = stk.top(); stk.pop(); C[u] = a.second; ++cnt; if (cnt == a.first) goto label; // assert(cnt < a.first); } } } label:; C[u] = 0; paint(u, b.first, b.second); for (int i = 0; i < n; ++i) if (!C[i]) C[i] = c.second; return C; } return C; } #ifndef split int main() { freopen("split.inp", "r", stdin); freopen("split.out", "w", stdout); int n, m, a, b, c; assert(5 == scanf("%d%d%d%d%d", &n, &m, &a, &b, &c)); vector <int> p(m), q(m); for (int i = 0; i < m; ++i) assert(2 == scanf("%d%d", &p[i], &q[i])); vector <int> result = find_split(n, a, b, c, p, q); for (int i = 0; i < result.size(); ++i) printf("%s%d", ((i > 0) ? " " : ""), result[i]); printf("\n"); return 0; } #endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...