1+ /*
2+ *Description:* Computes the virtual tree given the nodes in $O(K log V)$, uses binary lifting and works for directed and undirected graphs.
3+ *Status:* Tested
4+ */
5+ struct virtual_tree {
6+ int n,timer,lg;
7+ vector<int > tin,tout,dep;
8+ vector<vector<int >> up,adj_vt;
9+ void dfs (int u, int p, vector<vector<int >> & adj){
10+ tin[u] = ++timer;
11+ up[u][0 ] = p;
12+ for (int i = 1 ; i <= lg; i++)
13+ up[u][i] = up[up[u][i-1 ]][i-1 ];
14+ for (int v : adj[u]){
15+ if (v == p) continue ;
16+ dep[v] = dep[u]+1 ;
17+ dfs (v,u,adj);
18+ }
19+ tout[u] = timer;
20+ }
21+ bool is_ancestor (int u, int v) {
22+ return (tin[u] <= tin[v] && tout[u] >= tout[v]);
23+ }
24+ int lca (int u, int v){
25+ if (is_ancestor (u,v)) return u;
26+ if (is_ancestor (v,u)) return v;
27+ for (int i = lg; i >= 0 ; i--)
28+ if (!is_ancestor (up[u][i],v))
29+ u = up[u][i];
30+ return up[u][0 ];
31+ }
32+ virtual_tree (vector<vector<int >> & adj, int logn = 20 ){
33+ n = adj.size (); timer = 0 ; lg = logn;
34+ tin.resize (n); tout.resize (n); dep.resize (n,0 );
35+ up.assign (n,vector<int >(lg+1 ));
36+ adj_vt.resize (n); dfs (0 ,0 ,adj);
37+ }
38+ // builds the virtual tree in adj_vt, and returns the root
39+ int build (vector<int > nodes){
40+ assert (!nodes.empty ());
41+ auto cmp = [&](int u, int v){ return (tin[u] < tin[v]); };
42+ sort (nodes.begin (),nodes.end (),cmp);
43+ int k = nodes.size ();
44+ for (int i = 1 ; i < k; i++)
45+ nodes.push_back (lca (nodes[i-1 ],nodes[i]));
46+ sort (nodes.begin (),nodes.end (),cmp);
47+ nodes.erase (unique (nodes.begin (),nodes.end ()),nodes.end ());
48+ for (int v : nodes) adj_vt[v].clear ();
49+ vector<int > st = {nodes[0 ]};
50+ for (int i = 1 ; i < nodes.size (); i++){
51+ int u = nodes[i];
52+ while (st.size () >= 2 && !is_ancestor (st.back (),u)){
53+ adj_vt[st[st.size ()-2 ]].push_back (st.back ());
54+ st.pop_back ();
55+ }
56+ st.push_back (u);
57+ }
58+ while (st.size () >= 2 ){
59+ adj_vt[st[st.size ()-2 ]].push_back (st.back ());
60+ st.pop_back ();
61+ }
62+ return nodes[0 ];
63+ }
64+ };
0 commit comments