This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/graph/simple/connectedComponents.hpp"
与えられた無向グラフ $G(V, E)$ を連結成分に分解します。
ある頂点の二つ組 $(u, v)$ $u \in V, v \in V$ について、 $u$ から $v$ へのパスが存在する時またその時に限り $u$ と $v$ は同じ連結成分に属します。
コンストラクタ
zawa::connectedComponents(const std::vector<std::vector<int>>& G)
zawa::connectedComponents<cost_type> cc(const std::vector<std::vector<std::pair<int, cost_type>>>& G)
G
: グラフの隣接リストを表すstd::vector<std::vector<int>>
zawa::read_graph
を用いるとAtCoderの入力形式から対応するG
を作ることができますstd::vector<std::vector<std::pair<int, cost_type>>>
です。オペレータ
inline std::vector<int> operator[](int i) const
id
を返します。メンバ関数
inline std::size_t size() const
inline std::size_t size(int x) const
x
が属する連結成分の頂点数を返します。inline std::vector<std::vector<int>> comps() const
groups
と同じノリですinline std::vector<int> comp(int id) const
id
が振られた連結成分の頂点集合を返します。
cc.comps()[id]
と等価です。bool same(int i, int j) const
cc[i] == cc[j]
と等価です。#pragma once
#include <vector>
#include <stack>
namespace zawa {
class connectedComponents {
private:
std::vector<int> ids;
std::vector<std::vector<int>> groups;
void build(const std::vector<std::vector<int>>& G) {
int id = 0;
for (int i = 0 ; i < (int)G.size() ; i++) {
if (ids[i] == -1) {
ids[i] = id;
std::stack<int> stk({ i });
while (stk.size()) {
int v = stk.top();
stk.pop();
for (auto x : G[v]) {
if (ids[x] == -1) {
ids[x] = id;
stk.push(x);
}
}
}
id++;
}
}
groups = std::vector(id, std::vector(0, 0));
for (int i = 0 ; i < (int)ids.size() ; i++) {
groups[ids[i]].push_back(i);
}
}
public:
connectedComponents(const std::vector<std::vector<int>>& G) : ids(G.size(), -1) {
build(G);
}
template <class cost_type>
connectedComponents(const std::vector<std::vector<std::pair<int, cost_type>>>& G) : ids(G.size(), -1) {
std::vector tmpG(G.size(), std::vector(0, 0));
for (int i = 0 ; i < (int)G.size() ; i++) {
for (auto [x, _] : G[i]) {
tmpG[i].push_back(x);
}
}
build(tmpG);
}
inline int operator [](int i) const {
return ids[i];
}
inline std::size_t size() const {
return groups.size();
}
inline std::size_t size(int x) const {
return groups[ids[x]].size();
}
inline std::vector<std::vector<int>> comps() const {
return groups;
}
inline std::vector<int> comp(int id) const {
return groups[id];
}
bool same(int i, int j) const {
return ids[i] == ids[j];
}
};
} // namespace zawa
#line 2 "src/graph/simple/connectedComponents.hpp"
#include <vector>
#include <stack>
namespace zawa {
class connectedComponents {
private:
std::vector<int> ids;
std::vector<std::vector<int>> groups;
void build(const std::vector<std::vector<int>>& G) {
int id = 0;
for (int i = 0 ; i < (int)G.size() ; i++) {
if (ids[i] == -1) {
ids[i] = id;
std::stack<int> stk({ i });
while (stk.size()) {
int v = stk.top();
stk.pop();
for (auto x : G[v]) {
if (ids[x] == -1) {
ids[x] = id;
stk.push(x);
}
}
}
id++;
}
}
groups = std::vector(id, std::vector(0, 0));
for (int i = 0 ; i < (int)ids.size() ; i++) {
groups[ids[i]].push_back(i);
}
}
public:
connectedComponents(const std::vector<std::vector<int>>& G) : ids(G.size(), -1) {
build(G);
}
template <class cost_type>
connectedComponents(const std::vector<std::vector<std::pair<int, cost_type>>>& G) : ids(G.size(), -1) {
std::vector tmpG(G.size(), std::vector(0, 0));
for (int i = 0 ; i < (int)G.size() ; i++) {
for (auto [x, _] : G[i]) {
tmpG[i].push_back(x);
}
}
build(tmpG);
}
inline int operator [](int i) const {
return ids[i];
}
inline std::size_t size() const {
return groups.size();
}
inline std::size_t size(int x) const {
return groups[ids[x]].size();
}
inline std::vector<std::vector<int>> comps() const {
return groups;
}
inline std::vector<int> comp(int id) const {
return groups[id];
}
bool same(int i, int j) const {
return ids[i] == ids[j];
}
};
} // namespace zawa