在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。 如果有向图G的每两个顶点都强连通,称G是一个强连通图。 非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。
C++代码如下:(证明见《算法概论》)
#include <iostream>
#include<list>
#include<stack>
const int MAX = 100;
int clock = 1;//timestamp
using namespace std;
class Graph
{
int n;//顶点个数
int m;//边数
list<int> *adj;//邻接表
int visited[MAX];
int pre[MAX];//discovery time
int post[MAX];//finishing time
stack<int> post_sort;
void explore(int u,int opt);//遍历u的邻接点
public:
Graph(int n);//构造函数
~Graph();//析构函数
void addEdge(int u, int v);//添加边
void DFS();//深度优先搜索
void TransposedMap(const Graph &g);//图的转置
void SCC(const Graph &g);//强连通分量
};
Graph::Graph(int n)
{
this->n = n;
adj = new list<int>[n];
}
Graph::~Graph()
{
delete[]adj;
}
void Graph::addEdge(int u, int v)
{
adj[u].push_back(v);
}
void Graph::explore(int u,int opt)
{
visited[u] = 1;
pre[u] = clock;
clock++;
list<int>::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); i++)
if (!visited[*i])
explore(*i,opt);
post[u] = clock;
if (opt == 1)
post_sort.push(u);
else
cout << u << " ";
clock++;
}
void Graph::DFS()
{
for (int i = 0; i < n; i++)
visited[i] = 0;
for (int i = 0; i < n; i++)
{
if (!visited[i])
explore(i,1);
}
}
void Graph::TransposedMap(const Graph &g)
{
for (int u = 0; u < n; u++)
{
list<int>::iterator i;
for (i = g.adj[u].begin(); i != g.adj[u].end(); i++)
this->addEdge(*i, u);
}
}
void Graph::SCC(const Graph &g)
{
Graph gt(n);
gt.TransposedMap(g);
gt.DFS();
cout << "连通分量为:"<<endl;
while (!gt.post_sort.empty())
{
int v=gt.post_sort.top();
gt.post_sort.pop();
if (!visited[v])
{
explore(v,0);
cout << endl;
}
}
}
int main()
{
int n, m;//顶点数,边数
cin >> n >> m;
Graph g(n);
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
g.addEdge(u, v);
}
g.SCC(g);
}