强连通分量(Strongly Connected Component)是图论中的一个概念,指的是在有向图中,任意两个顶点之间都存在一条有向路径。强连通分量可以将图中的顶点划分为若干个集合,每个集合内的顶点互相可达,而不同集合之间的顶点不可达。
以下是C++实现强连通分量的代码:
#include<iostream>
#include<list>
#include<stack>
#include<vector>
using namespace std;
class Graph {
int V;
list<int> *adj;
void fillOrder(int v, vector<bool> &visited, stack<int> &s);
void DFS(int v, vector<bool> &visited);
public:
Graph(int V);
void addEdge(int v, int w);
void printSCCs();
Graph getTranspose();
};
Graph::Graph(int V) {
this->V = V;
adj = new list<int>[V];
}
void Graph::addEdge(int v, int w) {
adj[v].push_back(w);
}
void Graph::fillOrder(int v, vector<bool> &visited, stack<int> &s) {
visited[v] = true;
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i) {
if (!visited[*i])
fillOrder(*i, visited, s);
}
s.push(v);
}
void Graph::DFS(int v, vector<bool> &visited) {
visited[v] = true;
cout << v << " ";
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i) {
if (!visited[*i])
DFS(*i, visited);
}
}
Graph Graph::getTranspose() {
Graph g(V);
for(int v = 0; v < V; ++v) {
list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i) {
g.adj[*i].push_back(v);
}
}
return g;
}
void Graph::printSCCs() {
stack<int> s;
vector<bool> visited(V, false);
for(int v = 0; v < V; ++v) {
if (!visited[v])
fillOrder(v, visited, s);
}
Graph gr = getTranspose();
fill(visited.begin(), visited.end(), false);
while (!s.empty()) {
int v = s.top();
s.pop();
if (!visited[v]) {
gr.DFS(v, visited);
cout << endl;
}
}
}
int main() {
Graph g(5);
g.addEdge(1, 0);
g.addEdge(0, 2);
g.addEdge(2, 1);
g.addEdge(0, 3);
g.addEdge(3, 4);
cout << "Strongly Connected Components:\n";
g.printSCCs();
return 0;
}
该代码使用了深度优先搜索(DFS)算法来实现强连通分量。首先,使用DFS遍历图,将顶点按遍历结束时间的逆序压入栈中。然后,将图进行转置,即将有向边的方向反转。接下来,按栈中顶点的顺序遍历转置后的图,并输出其中的强连通分量。
在上面的示例中,创建了一个有向图,并添加了5个顶点和5个边。然后,使用printSCCs函数找到并输出强连通分量。输出结果为:
Strongly Connected Components:
4
3
0 2 1