This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "src/Graph/IncrementalBridgeConnectivity.hpp"
IncrementalBridgeConnectivity
クラスメンバ関数 | 概要 |
---|---|
IncrementalBridgeConnectivity(n) |
コンストラクタ. 頂点の数 $n$ を渡す. |
add_edge(u,v) |
辺 $(u,v)$ を追加する. |
leader(v) |
頂点 $v$ が属する二辺連結成分の代表頂点を返す. |
size(v) |
頂点 $v$ が属する二辺連結成分のサイズを返す. |
two_edge_connected(u,v) |
頂点 $u,v$ が共通の二辺連結成分に属するなら true , それ以外なら false を返す. |
connected(u,v) |
頂点 $u,v$ が連結なら true , それ以外なら false を返す. |
https://scrapbox.io/data-structures/Incremental_Bridge-Connectivity
#pragma once
#include <utility>
#include <vector>
class IncrementalBridgeConnectivity {
std::vector<int> cp, bp, bbf, z;
int t;
inline int crt(int v) { return cp[v] < 0 ? v : cp[v]= crt(cp[v]); }
inline int par(int v) { return bbf[v] < 0 ? -1 : leader(bbf[v]); }
public:
IncrementalBridgeConnectivity(int n): cp(n, -1), bp(n, -1), bbf(n, -1), z(n), t(0) {}
inline int leader(int v) { return bp[v] < 0 ? v : bp[v]= leader(bp[v]); }
int size(int v) { return -bp[leader(v)]; }
bool two_edge_connected(int u, int v) { return leader(u) == leader(v); }
bool connected(int u, int v) { return crt(u) == crt(v); }
void add_edge(int u, int v) {
int a= crt(u= leader(u)), b= crt(v= leader(v));
if (a == b)
for (++t, a= u, b= v;;) {
if (z[a] == t) {
for (int w: {u, v})
for (int p; w= leader(w), w != a; bp[a]+= bp[w], bp[w]= a, w= p)
if (p= bbf[w], bbf[w]= bbf[a]; bp[a] > bp[w]) std::swap(w, a);
return;
}
if (z[a]= t, a= par(a); b != -1) std::swap(a, b);
}
if (cp[a] < cp[b]) std::swap(u, v), cp[a]+= cp[b], cp[b]= a;
else cp[b]+= cp[a], cp[a]= b;
for (int p; u != -1; u= p) p= par(u), bbf[u]= v, v= u;
}
};
#line 2 "src/Graph/IncrementalBridgeConnectivity.hpp"
#include <utility>
#include <vector>
class IncrementalBridgeConnectivity {
std::vector<int> cp, bp, bbf, z;
int t;
inline int crt(int v) { return cp[v] < 0 ? v : cp[v]= crt(cp[v]); }
inline int par(int v) { return bbf[v] < 0 ? -1 : leader(bbf[v]); }
public:
IncrementalBridgeConnectivity(int n): cp(n, -1), bp(n, -1), bbf(n, -1), z(n), t(0) {}
inline int leader(int v) { return bp[v] < 0 ? v : bp[v]= leader(bp[v]); }
int size(int v) { return -bp[leader(v)]; }
bool two_edge_connected(int u, int v) { return leader(u) == leader(v); }
bool connected(int u, int v) { return crt(u) == crt(v); }
void add_edge(int u, int v) {
int a= crt(u= leader(u)), b= crt(v= leader(v));
if (a == b)
for (++t, a= u, b= v;;) {
if (z[a] == t) {
for (int w: {u, v})
for (int p; w= leader(w), w != a; bp[a]+= bp[w], bp[w]= a, w= p)
if (p= bbf[w], bbf[w]= bbf[a]; bp[a] > bp[w]) std::swap(w, a);
return;
}
if (z[a]= t, a= par(a); b != -1) std::swap(a, b);
}
if (cp[a] < cp[b]) std::swap(u, v), cp[a]+= cp[b], cp[b]= a;
else cp[b]+= cp[a], cp[a]= b;
for (int p; u != -1; u= p) p= par(u), bbf[u]= v, v= u;
}
};