Submission #424530

#TimeUsernameProblemLanguageResultExecution timeMemory
424530timmyfengSimurgh (IOI17_simurgh)C++17
0 / 100
1 ms204 KiB
#include <bits/stdc++.h> using namespace std; #include "simurgh.h" const int N = 500; int par[N], edge[N], depth[N], deg[N], matches[N], dsu[N], n; bool royal[N], visited[N], observed[N]; vector<int> span, ans, not_ans, u, v; vector<array<int, 2>> adj[N]; void dfs(int u) { visited[u] = true; for (auto [c, e] : adj[u]) { if (!visited[c]) { span.push_back(e); depth[c] = depth[u] + 1; edge[c] = e; par[c] = u; dfs(c); } } } int find(int u) { return dsu[u] < 0 ? u : dsu[u] = find(dsu[u]); } bool unite(int u, int v) { u = find(u), v = find(v); if (u != v) { if (-dsu[u] > -dsu[v]) { swap(u, v); } dsu[v] += dsu[u]; dsu[u] = v; return true; } return false; } vector<int> get(vector<int> tree) { fill(dsu, dsu + n, -1); tree.insert(tree.begin(), ans.begin(), ans.end()); tree.insert(tree.end(), not_ans.begin(), not_ans.end()); vector<int> res; for (auto i : tree) { if (unite(u[i], v[i])) { res.push_back(i); } } return res; } vector<int> find_roads(int n, vector<int> u, vector<int> v) { int m = u.size(); ::n = n, ::u = u, ::v = v; for (int i = 0; i < m; ++i) { adj[u[i]].push_back({v[i], i}); adj[v[i]].push_back({u[i], i}); } dfs(0); int init = count_common_roads(span); for (int i = 0; i < m; ++i) { if (depth[u[i]] > depth[v[i]]) { swap(u[i], v[i]); } if (depth[u[i]] + 1 == depth[v[i]]) { continue; } int reference = -1, mini = n - 1, maxi = 0; for (int j = v[i]; j != u[i]; j = par[j]) { vector<int> cycle = span; cycle.erase(find(cycle.begin(), cycle.end(), edge[j])); cycle.push_back(i); int value = -1; if (!observed[j]) { value = matches[j] = count_common_roads(cycle); } else if (reference == -1) { value = count_common_roads(cycle); reference = j; } if (value != -1) { mini = min(mini, value); maxi = max(maxi, value); } } for (int j = v[i]; j != u[i]; j = par[j]) { if (!observed[j]) { observed[j] = true; if (mini == maxi) { if (reference == -1) { royal[j] = mini < init; } else { royal[j] = royal[reference]; } } else { royal[j] = matches[j] == mini; } } } } for (int i = 1; i < n; ++i) { (royal[i] ? ans : not_ans).push_back(edge[i]); } vector<int> stk; for (int i = 0; i < n; ++i) { vector<int> star; for (auto [j, e] : adj[i]) { star.push_back(e); } star = get(star); deg[i] = count_common_roads(star) - ans.size(); if (deg[i] == 1) { stk.push_back(i); } } while (!stk.empty()) { int i = stk.back(); stk.pop_back(); if (deg[i] == 0) { continue; } int low = 0, high = adj[i].size() - 1; while (low < high) { int mid = (low + high) / 2; vector<int> star; for (int j = 0; j <= mid; ++j) { star.push_back(adj[i][j][1]); } star = get(star); if (count_common_roads(star) > (int) ans.size()) { high = mid; } else { low = mid + 1; } } auto [j, e] = adj[i][low]; ans.push_back(e); if (--deg[j] == 1) { stk.push_back(j); } } 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...