Skip to content

Commit 7c73707

Browse files
authored
Added virtual-tree.cpp (#83)
* Added tarjan for scc. * Added virtual-tree.cpp. * Added virtual-tree.cpp to wf-tracker. * Fix comment bug.
1 parent b2bd3ce commit 7c73707

3 files changed

Lines changed: 66 additions & 0 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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+
};

‎tracker-wf.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ content:
1717
- lca-rmq.cpp
1818
- hld.cpp
1919
- centroid-decomposition.cpp
20+
- virtual-tree.cpp
2021
- connectivity:
2122
- tarjan.cpp
2223
- tarjan-scc.cpp

‎tracker.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ content:
135135
- hld.cpp
136136
- ahld.cpp
137137
- centroid-decomposition.cpp
138+
- virtual-tree.cpp
138139
- shortest-paths:
139140
- floyd-warshall.cpp
140141
- dijkstra.cpp

0 commit comments

Comments
 (0)