-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbridge_tree.cpp
More file actions
76 lines (57 loc) · 2.07 KB
/
Copy pathbridge_tree.cpp
File metadata and controls
76 lines (57 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
-> Bridge Tree
-> Bridges in a graph divide the graph into different components such that when we traverse a bridge, we move from one such component to another. Let’s call these components as bridge components.
-> A "bridge tree" is a tree obtained by shrinking each of the bridge components of the graph into a single node such that an edge between two nodes in the resulting tree correspond to the bridge edge in the original graph connecting two different bridge components represented by the two nodes of the tree.
-> ref: https://tanujkhattar.wordpress.com/2016/01/10/the-bridge-tree-of-a-graph/
*/
vector<int> adj[N], disc(N), low(N);
bool vis[N];
vector<int> bridge_tree[N]; // adjacency list for bridge tree
vector<int> comp(N); // comp[i] -> component no. for node 'i'
stack<int> stk;
int tim = 1, comp_cnt = 1;
void dfs(int x, int par) {
vis[x] = true;
disc[x] = low[x] = tim++;
for (auto c : adj[x]) {
if (c == par)
continue;
if (!vis[c]) {
stk.push(x);
stk.push(c);
dfs(c, x);
low[x] = min(low[x], low[c]);
if (low[c] > disc[x]) { // edge (x, c) is a bridge
while (true) {
comp[stk.top()] = comp_cnt;
stk.pop();
if (stk.top() == x)
break;
}
++comp_cnt;
}
} else if (disc[c] < low[x]) {
low[x] = disc[c];
}
}
if (par == -1) {
while (!stk.empty()) {
comp[stk.top()] = compCnt;
stk.pop();
}
}
}
void constructBridgeTree(int n) {
dfs(1, -1);
repa(i, 1, n) {
for (auto c : adj[i]) {
if (comp[i] != comp[c])
bridge_tree[comp[i]].pb(comp[c]);
}
}
// repa(i, 1, n)
// cout << comp[i] << " ";
// cout << "\n";
// repa(i, 1, n)
// show(i, bridge_tree[i]);
}