This documentation is automatically generated by online-judge-tools/verification-helper
#include "Graph/strongly_connected_component.hpp"#pragma once
#include "graph.hpp"
#include <vector>
template <class Cost = int>
struct StronglyConnectedComponents {
Graph<Cost> graph, rgraph;
std::vector<bool> visited;
std::vector<int> stk;
// id[v] = 頂点vはgroups[id[v]]に属する
std::vector<int> id;
std::vector<std::vector<int>> groups;
explicit StronglyConnectedComponents(const Graph<Cost>& g)
: graph(g), visited(graph.size(), false), id(graph.size(), -1) {
revinit();
for (int v = 0; v < (int)graph.size(); ++v) dfs(v);
while (!stk.empty()) {
int v = stk.back();
stk.pop_back();
if (id[v] < 0) {
groups.emplace_back();
rdfs(v);
}
}
}
void revinit() {
rgraph = Graph<Cost>(graph.size());
for (int v = 0; v < (int)graph.size(); ++v) {
for (const auto& e : graph[v]) {
rgraph[e.dst].emplace_back(e.dst, v, e.cost);
}
}
}
void dfs(int v) {
if (visited[v]) return;
visited[v] = true;
for (const auto& e : graph[v]) dfs(e.dst);
stk.push_back(v);
}
void rdfs(int v) {
if (id[v] >= 0) return;
id[v] = groups.size() - 1;
groups.back().push_back(v);
for (const auto& e : rgraph[v]) rdfs(e.dst);
}
};#line 2 "Graph/strongly_connected_component.hpp"
#line 2 "Graph/graph.hpp"
#include <vector>
template <class Cost = int>
struct Edge {
int src, dst;
Cost cost;
Edge() = default;
Edge(int src, int dst, Cost cost = 1)
: src(src), dst(dst), cost(cost){};
bool operator<(const Edge<Cost>& e) const { return cost < e.cost; }
bool operator>(const Edge<Cost>& e) const { return cost > e.cost; }
};
template <class Cost = int>
struct Graph : public std::vector<std::vector<Edge<Cost>>> {
using std::vector<std::vector<Edge<Cost>>>::vector;
void span(bool direct, int src, int dst, Cost cost = 1) {
(*this)[src].emplace_back(src, dst, cost);
if (!direct) (*this)[dst].emplace_back(dst, src, cost);
}
};
#line 4 "Graph/strongly_connected_component.hpp"
#line 6 "Graph/strongly_connected_component.hpp"
template <class Cost = int>
struct StronglyConnectedComponents {
Graph<Cost> graph, rgraph;
std::vector<bool> visited;
std::vector<int> stk;
// id[v] = 頂点vはgroups[id[v]]に属する
std::vector<int> id;
std::vector<std::vector<int>> groups;
explicit StronglyConnectedComponents(const Graph<Cost>& g)
: graph(g), visited(graph.size(), false), id(graph.size(), -1) {
revinit();
for (int v = 0; v < (int)graph.size(); ++v) dfs(v);
while (!stk.empty()) {
int v = stk.back();
stk.pop_back();
if (id[v] < 0) {
groups.emplace_back();
rdfs(v);
}
}
}
void revinit() {
rgraph = Graph<Cost>(graph.size());
for (int v = 0; v < (int)graph.size(); ++v) {
for (const auto& e : graph[v]) {
rgraph[e.dst].emplace_back(e.dst, v, e.cost);
}
}
}
void dfs(int v) {
if (visited[v]) return;
visited[v] = true;
for (const auto& e : graph[v]) dfs(e.dst);
stk.push_back(v);
}
void rdfs(int v) {
if (id[v] >= 0) return;
id[v] = groups.size() - 1;
groups.back().push_back(v);
for (const auto& e : rgraph[v]) rdfs(e.dst);
}
};