Skip to content

Commit

Permalink
feat: bridge support
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Feb 27, 2025
1 parent 44b6139 commit fd543d0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
42 changes: 28 additions & 14 deletions src/code/graph/v_bcc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,52 @@

namespace tifa_libs::graph {

template <bool get_cut = false, bool get_belongs = true>
template <bool get_vcut = false, bool get_ecut = false, bool get_belongs = true>
struct v_bcc {
static_assert(!get_ecut || (!get_vcut && !get_belongs));
vecu dfn, low;
vvecu belongs;
vecb cut;
vecb vcut;
vecptu ecut;

//! g should be undirect
template <bool with_deg>
CEXP v_bcc(alist<with_deg> CR g) NE : dfn(g.size()), low(g.size()) {
if CEXP (get_cut) cut = vecb(g.size());
if CEXP (get_vcut) vcut = vecb(g.size());
if CEXP (get_ecut) ecut.reserve(g.size());
vecu stk;
u32 cnt = 0, start;
auto tarjan = [&](auto&& f, u32 u, u32 fa) -> void {
u32 son = 0;
bool ecut_flag = false;
low[u] = dfn[u] = ++cnt;
if CEXP (get_belongs) stk.push_back(u);
for (auto v : g[u])
if (!dfn[v]) {
++son, f(f, v, u), low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
if CEXP (get_cut)
if (u != start) cut[u] = true;
if CEXP (get_belongs) {
vecu now;
now.reserve(stk.size() + 1);
while (!stk.empty() && (now.empty() || now.back() != v)) now.push_back(stk.back()), stk.pop_back();
now.push_back(u), now.shrink_to_fit(), belongs.push_back(now);
if CEXP (get_ecut) {
if (low[v] > dfn[u]) ecut.emplace_back(v, u);
} else {
if (low[v] >= dfn[u]) {
if CEXP (get_vcut)
if (u != start) vcut[u] = true;
if CEXP (get_belongs) {
vecu res;
u32 p;
do res.push_back(p = stk.back()), stk.pop_back();
while (v != p);
res.push_back(u), belongs.emplace_back(std::move(res));
}
}
}
} else if (v != fa) low[u] = min(low[u], dfn[v]);
if CEXP (get_cut)
if (u == start && son >= 2) cut[u] = true;
} else {
if CEXP (get_ecut) {
if (v != fa || ecut_flag) low[u] = min(low[u], dfn[v]);
else ecut_flag = true;
} else if (v != fa) low[u] = min(low[u], dfn[v]);
}
if CEXP (get_vcut)
if (u == start && son >= 2) vcut[u] = true;
if CEXP (get_belongs)
if (!~fa && !son) belongs.push_back({u});
};
Expand Down
4 changes: 2 additions & 2 deletions src/test_cpverifier/aizu-grl/grl_3_a.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ int main() {
std::cin >> u >> v;
g.add_arc(u, v), g.add_arc(v, u);
}
tifa_libs::graph::v_bcc<true, false> bcc(g);
tifa_libs::graph::v_bcc<true, false, false> bcc(g);
flt_ (u32, i, 0, n)
if (bcc.cut[i]) std::cout << i << '\n';
if (bcc.vcut[i]) std::cout << i << '\n';
return 0;
}
17 changes: 17 additions & 0 deletions src/test_cpverifier/aizu-grl/grl_3_b.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/all/GRL_3_B"

Check failure on line 1 in src/test_cpverifier/aizu-grl/grl_3_b.test.cpp

View workflow job for this annotation

GitHub Actions / verify (01)

Failed to test src/test_cpverifier/aizu-grl/grl_3_b.test.cpp

#include "../../code/graph/v_bcc.hpp"

int main() {
std::cin.tie(nullptr)->std::ios::sync_with_stdio(false);
u32 n, m;
std::cin >> n >> m;
tifa_libs::graph::alist g(n);
for (u32 i = 0, u, v; i < m; ++i) {
std::cin >> u >> v;
g.add_arc(u, v), g.add_arc(v, u);
}
tifa_libs::graph::v_bcc<false, true, false> bcc(g);
for (auto [v, u] : bcc.ecut) std::cout << v << ' ' << u << '\n';
return 0;
}

0 comments on commit fd543d0

Please sign in to comment.