Submission #865084

#TimeUsernameProblemLanguageResultExecution timeMemory
865084overwatch9Railway (BOI17_railway)C++17
100 / 100
186 ms30420 KiB
#include <iostream> #include <vector> #include <algorithm> using namespace std; vector <vector <pair <int, int>>> adj; vector <vector <int>> anc; vector <int> visit, finish, parent_edge; vector <pair <int, int>> edges; int t = 0; void dfs(int s, int p) { visit[s] = t++; anc[s][0] = p; for (int i = 1; i < 20; i++) anc[s][i] = anc[anc[s][i-1]][i-1]; for (auto i : adj[s]) { if (i.first == p) continue; parent_edge[i.first] = i.second; dfs(i.first, s); } finish[s] = t++; } bool is_ancestor(int a, int b) { return visit[a] <= visit[b] && finish[a] >= finish[b]; } int get_lca(int a, int b) { if (is_ancestor(a, b)) return a; if (is_ancestor(b, a)) return b; int lca = a; for (int i = 19; i >= 0; i--) { if (!is_ancestor(anc[lca][i], b)) lca = anc[lca][i]; } return anc[lca][0]; } bool comp(int a, int b) { return visit[a] < visit[b]; } struct stree { #define lc v*2 #define rc v*2+1 vector <int> tree; stree (int s) { tree.resize(s*4); } void pushup(int v) { tree[v] = tree[lc] + tree[rc]; } void update(int v, int tl, int tr, int p, int val) { if (tl > p || tr < p) return; if (tl == tr) { tree[v] += val; return; } int tm = (tl + tr) / 2; update(lc, tl, tm, p, val); update(rc, tm+1, tr, p, val); pushup(v); } int query(int v, int tl, int tr, int l, int r) { if (tl > r || tr < l) return 0; if (tl >= l && tr <= r) return tree[v]; int tm = (tl + tr) / 2; int a = query(lc, tl, tm, l, r); int b = query(rc, tm+1, tr, l, r); return a + b; } }; int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int n, m, k; cin >> n >> m >> k; adj.resize(n+1); parent_edge = visit = finish = vector <int> (n+1); anc = vector <vector <int>> (n+1, vector <int> (20)); edges.resize(n+1); for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; edges[i] = {a, b}; adj[a].push_back({b, i}); adj[b].push_back({a, i}); } dfs(1, 1); stree tree(t+1); for (int i = 0; i < m; i++) { int f; cin >> f; vector <int> chosen(f); for (int j = 0; j < f; j++) cin >> chosen[j]; sort(chosen.begin(), chosen.end(), comp); chosen.push_back(chosen[0]); for (int j = 0; j < f; j++) { int a = chosen[j], b = chosen[j+1]; int lca = get_lca(a, b); tree.update(1, 0, t, visit[a], 1); tree.update(1, 0, t, visit[b], 1); tree.update(1, 0, t, visit[lca], -2); } } vector <int> approved; for (int i = 1; i <= n; i++) { int res = tree.query(1, 0, t, visit[i], finish[i]); if (res >= 2*k) { int edge_id = parent_edge[i]; if (edge_id != 0) approved.push_back(edge_id); } } sort(approved.begin(), approved.end()); cout << approved.size() << '\n'; for (auto i : approved) cout << i << ' '; 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...