@@ -29,8 +29,7 @@ template <typename ptr_t = size_t> struct TwoEdgeConnectedComponents {
2929
3030 void tarjan (ptr_t u, ptr_t parent_edge) {
3131 dfn[u] = low[u] = ++dfs_time;
32- stk.push (u);
33- in_stack[u] = true ;
32+ stk.push (u), in_stack[u] = true ;
3433
3534 for (const auto &[v, edge_id] : graph[u]) {
3635 if (edge_id == parent_edge)
@@ -75,8 +74,7 @@ template <typename ptr_t = size_t> struct StrongConnectedComponents {
7574
7675 void tarjan (ptr_t u) {
7776 dfn[u] = low[u] = ++dfs_time;
78- stk.push (u);
79- in_stack[u] = true ;
77+ stk.push (u), in_stack[u] = true ;
8078
8179 for (const auto &v : graph[u]) {
8280 if (!dfn[v])
@@ -102,6 +100,57 @@ template <typename ptr_t = size_t> struct StrongConnectedComponents {
102100 std::reverse (sccs.begin (), sccs.end ());
103101 }
104102};
103+
104+ template <typename ptr_t = size_t > struct BiconnectedComponents {
105+ ptr_t dfs_time = 0 ;
106+
107+ std::stack<ptr_t > stk;
108+ std::vector<ptr_t > dfn, low;
109+ std::vector<std::vector<ptr_t >> graph;
110+
111+ std::vector<bool > is_cut;
112+ std::vector<std::vector<ptr_t >> dccs;
113+
114+ BiconnectedComponents (ptr_t n) : dfn(n, 0 ), low(n, 0 ), graph(n), is_cut(n, false ) {}
115+
116+ void add_edge (ptr_t u, ptr_t v) {
117+ graph[u].push_back (v);
118+ graph[v].push_back (u);
119+ }
120+
121+ void tarjan (ptr_t u, bool is_root) {
122+ dfn[u] = low[u] = ++dfs_time, stk.push (u);
123+
124+ if (is_root && graph[u].empty ()) {
125+ dccs.emplace_back ();
126+ dccs.back ().push_back (u);
127+ return ;
128+ }
129+
130+ ptr_t child = 0 ;
131+ for (const auto &v : graph[u]) {
132+ if (!dfn[v]) {
133+ tarjan (v, false ), low[u] = std::min (low[u], low[v]);
134+ if (low[v] >= dfn[u]) {
135+ if (++child > 1 || !is_root)
136+ is_cut[u] = true ;
137+ dccs.emplace_back ();
138+ do
139+ dccs.back ().push_back (stk.top ()), stk.pop ();
140+ while (dccs.back ().back () != v);
141+ dccs.back ().push_back (u);
142+ }
143+ } else
144+ low[u] = std::min (low[u], dfn[v]);
145+ }
146+ }
147+
148+ void solve () {
149+ for (size_t i = 0 ; i < graph.size (); ++i)
150+ if (!dfn[i])
151+ tarjan (i, true );
152+ }
153+ };
105154} // namespace weilycoder
106155
107156#endif
0 commit comments