제출 #824582

#제출 시각아이디문제언어결과실행 시간메모리
824582erraySplit the Attractions (IOI19_split)C++17
22 / 100
122 ms29644 KiB
#include "split.h" #include <bits/stdc++.h> using namespace std; #ifdef DEBUG #include "/home/eagle/ioi19/d1/debug.h" #else #define debug(...) void(37) #endif struct DSU { vector<int> link; DSU(int n) { link.resize(n); iota(link.begin(), link.end(), 0); } int get(int v) { return link[v] = (v == link[v] ? v : get(link[v])); } bool unite(int x, int y) { x = get(x), y = get(y); if (x == y) { return false; } link[y] = x; return true; } }; vector<int> find_split(int N, int A, int B, int C, vector<int> P, vector<int> Q) { array<array<int, 2>, 3> ord{}; ord[0] = {A, 1}; ord[1] = {B, 2}; ord[2] = {C, 3}; sort(ord.begin(), ord.end()); vector<vector<int>> g(N); int M = int(P.size()); for (int i = 0; i < M; ++i) { g[P[i]].push_back(Q[i]); g[Q[i]].push_back(P[i]); } auto Build = [&](int root, vector<vector<int>>& dfs_g) { vector<int> size(N, 1); vector<bool> vis(N); vector<int> from(N, -1); vector<vector<int>> tree(N); function<void(int)> Dfs = [&](int v) { vis[v] = true; for (auto u : dfs_g[v]) { if (!vis[u]) { from[u] = (from[v] == -1 ? u : from[v]); Dfs(u); tree[v].push_back(u); tree[u].push_back(v); size[v] += size[u]; } } }; Dfs(root); return make_tuple(tree, size, from); }; auto[tree, size, from] = Build(0, g); debug(tree, size, from); int lower = N / 3; int upper = N - lower; int root = 0; while (true) { int go = -1; for (auto u : tree[root]) { if (size[u] > upper) { go = u; } } if (go == -1) { break; } size[root] = N - size[go]; size[go] = N; root = go; } tie(tree, size, from) = Build(root, tree); debug(root, size, from); for (auto u : tree[root]) { assert(size[u] <= upper); } DSU group(N); for (int i = 0; i < M; ++i) { if (from[P[i]] != -1 && from[Q[i]] != -1) { group.unite(from[P[i]], from[Q[i]]); } } vector<int> tot(N); for (auto u : tree[root]) { tot[group.get(u)] += size[u]; } int use = int(max_element(tot.begin(), tot.end()) - tot.begin()); debug(use); if (tot[use] < ord[0][0]) { return vector<int>(N, 0); } vector<int> ans(N, 3); ans[root] = 2; function<void(int, int&, int)> Set = [&](int v, int& left, int id) { --left; ans[v] = id; for (auto u : tree[v]) { if (ans[u] == 3 && left > 0) { Set(u, left, id); } } }; int small = ord[0][0]; for (auto u : tree[root]) { if (group.get(u) == use) { Set(u, small, 1); } } assert(small == 0); int middle = ord[1][0]; Set(root, middle, 2); assert(middle == 0); for (int i = 0; i < N; ++i) { ans[i] = ord[ans[i] - 1][1]; } return ans; }
#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...