Submission #1023162

#TimeUsernameProblemLanguageResultExecution timeMemory
1023162avighnaRigged Roads (NOI19_riggedroads)C++17
100 / 100
378 ms88756 KiB
#include <vector> #include <iostream> #include <numeric> #include <algorithm> #include <functional> class UFDS { public: std::vector<int> par; UFDS(int n) : par(n + 1) { std::iota(par.begin(), par.end(), 0); } int root(int x) { if (x == par[x]) { return x; } return par[x] = root(par[x]); } void merge(int x, int y) { x = root(x); y = root(y); if (x == y) { return; } par[y] = x; } }; const int N = 3e5 + 1; std::vector<int> adj[N]; std::vector<std::pair<int, int>> tree[N]; bool r[N], assigned[N]; int lift[N][20]; int depth[N], edge_to_num[N]; int main() { int n, e; std::cin >> n >> e; std::vector<std::pair<int, int>> edges; for (int i = 0, u, v; i < e; ++i) { std::cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); edges.push_back({u, v}); } for (int i = 0, v; i < n - 1; ++i) { std::cin >> v; --v; r[v] = true; tree[edges[v].first].push_back({edges[v].second, v}); tree[edges[v].second].push_back({edges[v].first, v}); } std::function<void(int, int)> dfs; dfs = [&](int node, int par) { for (auto &[i, v] : tree[node]) { if (i == par) { continue; } depth[i] = depth[node] + 1; lift[i][0] = node; edge_to_num[i] = v; dfs(i, node); } }; dfs(1, 0); for (int bt = 1; bt < 20; ++bt) { for (int i = 1; i <= n; ++i) { lift[i][bt] = lift[lift[i][bt - 1]][bt - 1]; } } auto lca = [&](int a, int b) { if (depth[a] < depth[b]) { std::swap(a, b); } int k = depth[a] - depth[b]; for (int bt = 0; bt < 20; ++bt) { if (k & (1 << bt)) { a = lift[a][bt]; } } if (a == b) { return a; } for (int bt = 19; bt >= 0; --bt) { if (lift[a][bt] != lift[b][bt]) { a = lift[a][bt]; b = lift[b][bt]; } } return lift[a][0]; }; int cur = 1; std::vector<int> p(e); UFDS dsu(n); for (int i = 0; i < e; ++i) { if (assigned[i]) { continue; } assigned[i] = true; auto [u, v] = edges[i]; int anc = lca(u, v); if (r[i]) { p[i] = cur++; if (depth[u] < depth[v]) { std::swap(u, v); } dsu.merge(v, u); continue; } std::vector<int> target_edges; for (auto &x : std::array<int, 2>({u, v})) { while (x != anc && depth[dsu.root(x)] >= depth[anc]) { x = dsu.root(x); if (x == anc) { break; } target_edges.push_back(edge_to_num[x]); dsu.merge(lift[x][0], x); x = lift[x][0]; } } std::sort(target_edges.begin(), target_edges.end()); for (auto &e : target_edges) { if (assigned[e]) { continue; } assigned[e] = true; p[e] = cur++; } p[i] = cur++; } for (auto &i : p) { std::cout << i << " "; } std::cout << "\n"; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...