Submission #762500

#TimeUsernameProblemLanguageResultExecution timeMemory
762500boris_mihovSplit the Attractions (IOI19_split)C++17
40 / 100
78 ms32424 KiB
#include "split.h" #include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <random> #include <vector> typedef long long llong; const int MAXN = 100000 + 10; const int INF = 1e9; int n, m; int aNum; int bNum; int cNum; int timer; int t[MAXN]; int sz[MAXN]; int low[MAXN]; bool vis[MAXN]; int comp[MAXN]; std::vector <int> g[MAXN]; std::vector <int> tree[MAXN]; std::vector <int> ans; int a, b, c; void reset() { for (int i = 1 ; i <= n ; ++i) { tree[i].clear(); low[i] = t[i] = sz[i] = vis[i] = comp[i] = false; } } void assignComponent(int node, int to) { comp[node] = to; for (const int &u : tree[node]) { assignComponent(u, to); } } bool dfs(int node, int par) { sz[node] = 1; vis[node] = true; t[node] = low[node] = ++timer; int remove = 0; std::vector <int> removeAble; std::vector <int> mandatory; for (const int &u : g[node]) { if (u == par) { continue; } if (vis[u]) { low[node] = std::min(low[node], t[node]); continue; } tree[node].push_back(u); if (dfs(u, node)) { return true; } sz[node] += sz[u]; low[node] = std::min(low[node], low[u]); if (low[u] < t[node]) { remove += sz[u]; removeAble.push_back(u); } else { mandatory.push_back(u); } } if (sz[node] >= a && remove + n - sz[node] >= b) { comp[node] = 1; for (const int &u : removeAble) { if (sz[node] - sz[u] >= a) { sz[node] -= sz[u]; } else { assignComponent(u, 1); } } for (const int &u : mandatory) { assignComponent(u, 1); } return true; } if (n - sz[node] >= a && sz[node] >= b) { std::fill(comp + 1, comp + 1 + n, 1); comp[node] = 0; for (const int &u : removeAble) { if (sz[node] - sz[u] >= b) { sz[node] -= sz[u]; } else { assignComponent(u, 0); } } for (const int &u : mandatory) { assignComponent(u, 0); } return true; return true; } return false; } int needed; void cutComponents(int node) { vis[node] = true; if (needed >= 1) { if (comp[node] == 1) { ans[node - 1] = aNum; } else { ans[node - 1] = bNum; } needed--; } for (const int &u : g[node]) { if (!vis[u] && comp[node] == comp[u]) { cutComponents(u); } } } std::mt19937 mt(420); std::vector <int> find_split(int N, int A, int B, int C, std::vector <int> u, std::vector <int> v) { n = N; a = A; b = B; c = C; aNum = 1; bNum = 2; cNum = 3; m = u.size(); if (a > b) { std::swap(a, b); std::swap(aNum, bNum); } if (a > c) { std::swap(a, c); std::swap(aNum, cNum); } if (b > c) { std::swap(b, c); std::swap(bNum, cNum); } for (int i = 0 ; i < m ; ++i) { g[u[i] + 1].push_back(v[i] + 1); g[v[i] + 1].push_back(u[i] + 1); } ans.resize(n, 0); bool res = false; for (int i = 0 ; i < 10000 && !res ; ++i) { res = dfs(mt()%n + 1, 0); } if (!res) { return ans; } std::fill(vis + 1, vis + 1 + n, false); for (int i = 1 ; i <= n ; ++i) { if (vis[i]) { continue; } if (comp[i] == 1) needed = a; else needed = b; cutComponents(i); } for (int i = 0 ; i < n ; ++i) { if (ans[i] == 0) { ans[i] = cNum; } } return ans; }

Compilation message (stderr)

split.cpp: In function 'void reset()':
split.cpp:33:50: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
   33 |         low[i] = t[i] = sz[i] = vis[i] = comp[i] = false;
      |                                          ~~~~~~~~^~~~~~~
#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...