Skip to content

Commit ebabb1b

Browse files
committed
add cuts with callback
1 parent ac4d0d0 commit ebabb1b

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#pragma once
2+
//! https://cp-algorithms.com/graph/cutpoints.html
3+
//! @code
4+
//! {
5+
//! vector<vector<pii>> adj(n);
6+
//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m);
7+
//! }
8+
//! vector<basic_string<array<int, 2>>> adj(n);
9+
//! rep (i, 0, m) {
10+
//! int u, v;
11+
//! cin >> u >> v;
12+
//! u--, v--;
13+
//! //self edges not allowed
14+
//! adj[u] += {v, i};
15+
//! adj[v] += {u, i};
16+
//! }
17+
//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m);
18+
//! @endcode
19+
//! @time O(n + m)
20+
//! @space O(n + m)
21+
/*
22+
auto cuts(const auto& adj, int m) {
23+
int n = sz(adj), num_bccs = 0, q = 0, s = 0;
24+
vi bcc_id(m, -1), is_cut(n), tin(n), st(m);
25+
auto dfs = [&](auto&& self, int v, int p) -> int {
26+
int low = tin[v] = ++q;
27+
for (auto [u, e] : adj[v]) {
28+
assert(v != u);
29+
if (e == p) continue;
30+
if (tin[u] < tin[v]) st[s++] = e;
31+
int lu = -1;
32+
low = min(low, tin[u] ?: (lu = self(self, u, e)));
33+
if (lu >= tin[v]) {
34+
is_cut[v] = p >= 0 || tin[v] + 1 < tin[u];
35+
while (bcc_id[e] < 0) bcc_id[st[--s]] = num_bccs;
36+
num_bccs++;
37+
}
38+
}
39+
return low;
40+
};
41+
rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1);
42+
return tuple{num_bccs, bcc_id, is_cut};
43+
}
44+
*/
45+
void cuts_callback(const auto& adj, auto f) {
46+
int n = ssize(adj), q = 0, s = 0;
47+
vector<int> tin(n), st(n);
48+
auto dfs = [&](auto&& self, int v, int p) -> int {
49+
int low = tin[v] = ++q;
50+
for (int u : adj[v]) if (u != p) {
51+
int siz = s, lu = 0;
52+
low = min(low, tin[u] ?: (lu = self(self, st[s++] = u, v)));
53+
if (lu >= tin[v]) {
54+
f(v, vector<int>(begin(st) + siz, begin(st) + s));
55+
s = siz;
56+
}
57+
}
58+
return low;
59+
};
60+
for (int i = 0; i <n; i++) if (!tin[i]) dfs(dfs, i, i);
61+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#define PROBLEM \
2+
"https://judge.yosupo.jp/problem/biconnected_components"
3+
#include "../template.hpp"
4+
#include "../../../library/graphs/bridges_cuts/cuts_callback.hpp"
5+
int main() {
6+
cin.tie(0)->sync_with_stdio(0);
7+
int n,m;
8+
cin>>n>>m;
9+
vector<basic_string<int>> adj(n);
10+
for (int i = 0; i <n; i++) {
11+
adj[i] += i;
12+
}
13+
for (int i = 0; i <m; i++) {
14+
int u,v;
15+
cin>>u>>v;
16+
adj[u] += v;
17+
adj[v] += u;
18+
}
19+
vector<bool> vis(n, 0);
20+
vector<vector<int>> all_bccs;
21+
cuts_callback(adj, [&](int v, const vi& nodes_bcc) {
22+
vis[v] = 1;
23+
for(int u : nodes_bcc){
24+
vis[u] = 1;
25+
}
26+
all_bccs.push_back(nodes_bcc);
27+
all_bccs.back().push_back(v);
28+
});
29+
for (int i = 0; i <n; i++) {
30+
if(!vis[i]) {
31+
all_bccs.push_back({i});
32+
}
33+
}
34+
cout << ssize(all_bccs) << '\n';
35+
for(const vector<int>& other_nodes : all_bccs) {
36+
cout<<ssize(other_nodes)<<' ';
37+
for(int v : other_nodes){
38+
cout<<v<<' ';
39+
}
40+
cout<<'\n';
41+
}
42+
return 0;
43+
}

0 commit comments

Comments
 (0)