1 /**
2 Unstable
3 */
4 module dkh.graph.dfstree;
5 
6 struct DFSTreeInfo {
7     int[] low, ord, par, vlis; //low, ord, parent, visitList
8     int[][] tr; //dfs tree(directed)
9     this(int n) {
10         low = new int[n];
11         ord = new int[n];
12         par = new int[n];
13         vlis = new int[n];
14         tr = new int[][](n);
15     }
16 }
17 
18 DFSTreeInfo dfsTree(T)(T g) {
19     import std.algorithm : min, each, filter;
20     import std.conv : to;
21     const int n = g.length.to!int;
22     auto info = DFSTreeInfo(n);
23     with(info) {
24         int co = 0;
25         bool[] used = new bool[](n);
26         void dfs(int p, int b) {
27             used[p] = true;
28             low[p] = ord[p] = co++;
29             par[p] = b;
30 
31             bool rt = true;
32             foreach (e; g[p]) {
33                 int d = e.to;
34                 if (rt && d == b) {
35                     rt = false;
36                     continue;
37                 }
38                 if (!used[d]) {
39                     dfs(d, p);
40                     low[p] = min(low[p], low[d]);
41                 } else {
42                     low[p] = min(low[p], ord[d]);
43                 }
44             }
45         }
46             
47         foreach (i; 0..n) {
48             if (used[i]) continue;
49             dfs(i, -1);
50         }
51         foreach (i; 0..n) {
52             if (par[i] == -1) continue;
53             tr[par[i]] ~= i;
54         }
55 //        par.filter!"a!=-1".each!((i, v) => tr[v] ~= i.to!int);
56         ord.each!((i, v) => vlis[v] = i.to!int);
57     }
58     return info;
59 }