#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#define ll long long
#define ld long double
#define pl pair<ll, ll>
#define vi vector<ll>
#define vii vector<vi>
#define viii vector<vii>
#define vc vector<char>
#define vcc vector<vc>
#define vp vector<pl>
#define mi map<ll,ll>
#define mc map<char,int>
#define sortx(X) sort(X.begin(),X.end());
#define all(X) X.begin(),X.end()
#define allr(X) X.rbegin(),X.rend()
#define ln '\n'
#define YES {cout << "YES\n"; return;}
#define NO {cout << "NO\n"; return;}
#define MUN {cout << "-1\n"; return;}
using namespace std;
const int MODE = 1e9+7;
class Graph {
public:
int size, SPSIZE;
vi Indeg, lvl;
vp Trav;
vector<vp> table;
vi dp;
void dfs( const vii &adj, int n, int p, ll deep) {
lvl[n] = deep;
Indeg[n] = Trav.size();
Trav.push_back({deep, n});
for (auto neg : adj[n]) {
if (neg == p) continue;
dfs(adj, neg, n, deep + 1);
Trav.push_back({deep, n});
}
}
void BuildLCA() {
ll n = Trav.size();
SPSIZE = ceil(log2(n));
table.resize(n, vp(SPSIZE + 1));
for (int i = 0; i < n; i++)
table[i][0] = Trav[i];
for (int j = 1; j <= SPSIZE; j++)
for (int i = 0; i <= n - (1 << j); i++)
table[i][j] = min(table[i][j - 1], table[i + (1 << (j - 1))][j - 1]);
}
ll LCA(ll a, ll b) {
ll l = Indeg[a], r = Indeg[b];
if (l > r) swap(l, r);
int j = (int)log2(r - l + 1);
return min(table[l][j], table[r - (1 << j) + 1][j]).second;
}
ll dist(ll a, ll b) {
return lvl[a] + lvl[b] - 2 * lvl[LCA(a, b)];
}
vector<vp> virtual_tree(vi &nodes) {
// compare in dfs order
auto cmp = [&](ll a, ll b) {
return Indeg[a] < Indeg[b];
};
sort(all(nodes), cmp);
ll n = nodes.size();
for (int i = 0; i < n-1; i++)
{
nodes.push_back(LCA(nodes[i], nodes[i+1]));
}
sort(all(nodes), cmp);
nodes.erase(unique(all(nodes)), nodes.end());
n = nodes.size();
vector<vp> adj(n);
stack<ll> st;
st.push(0);
for (int i = 1; i < n; i++)
{
while (LCA(nodes[st.top()], nodes[i]) != nodes[st.top()]) st.pop();
adj[st.top()].push_back({i, dist(nodes[st.top()], nodes[i])});
st.push(i);
}
return adj;
}
ll dfsquery(vector<vp> &adj, vi &V, ll n) {
ll cnt = 0;
for (auto [neg, w] : adj[n]) {
cnt += dfsquery(adj, V, neg);
}
if (!cnt) {
dp[V[n]]++;
} else {
dp[V[n]] += 1 - cnt;
}
return 1;
}
void query(vi nodes) {
set<ll> st(all(nodes));
auto adj = virtual_tree(nodes);
ll n = nodes.size();
dfsquery(adj, nodes, 0);
dp[nodes[0]]--;
}
Graph(ll n, const vii &adj) : size(n), lvl(n+1), Indeg(n+1), dp(n+1) {
dfs(adj, 1, 0, 1);
BuildLCA();
}
};
void req(vector<vp> &adj, vi &res, vi &dp, ll n, ll ed, ll k) {
for (auto [neg, ind] : adj[n]) if (ind != ed) {
req(adj, res, dp, neg, ind, k);
if (dp[neg] >= k) res.push_back(ind);
dp[n] += dp[neg];
}
}
void solve(int tc) {
ll n, m, k;
cin >> n >> m >> k;
vii adj(n + 1);
vector<vp> adjw(n + 1);
for (int i = 0; i < n-1; i++)
{
ll u, v; cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
adjw[u].push_back({v, i+1});
adjw[v].push_back({u, i+1});
}
Graph gr(n, adj);
while (m--)
{
ll s; cin >> s;
vi nd(s);
for (int i = 0; i < s; i++)
cin >> nd[i];
gr.query(nd);
}
vi res;
req(adjw, res, gr.dp, 1, 0, k);
sortx(res);
cout << res.size() << '\n';
for (auto a : res) cout << a << ' ';
cout << '\n';
}
signed main()
{
ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int size = 1;
// freopen("gathering.in", "r", stdin);
// freopen("gathering.out", "w", stdout);
// cin >> size;
for (int i = 1; i <= size ; i++) solve(i);
return 0;
}
# | 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... |