This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |