强连通分量:强连通子图(一个图可能不是强连通的,但它的子图可能是强连通的,这些子图被称为强连通分量)
代码参考
改写了一下,加了点注解
对于算法的理解,指路->【持续更新】算法学习—参考博客
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
const int V = 8;
int dfn[V]; //记录某一顶点被访问的时间点
int low[V]; //记录某一顶点通过有向边回溯到的最早的时间点
bool in_stack[V];
stack<int> s;
int g[V][V] = //邻接矩阵存图
{
{0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0},
{1,0,0,0,0,0,0,0},
{0,0,0,0,1,0,0,1},
{0,0,0,0,0,1,0,0},
{1,0,0,0,0,0,1,0},
{1,0,1,0,1,0,0,0},
{0,0,0,1,0,1,0,0}
};
void tarjan_dfs(int x)
{
static int time = 1;
dfn[x] = low[x] = time++;
s.push(x);
in_stack[x] = true;
for (int y = 0; y < V; y++)
{
if (g[x][y])
{
if (0 == dfn[y])
{
tarjan_dfs(y);
low[x] = min(low[x], low[y]);
}
else if (in_stack[y])
low[x] = min(low[x], dfn[y]);
}
}
if (dfn[x] == low[x])
{
int tmp;
do
{
tmp = s.top(); s.pop();
in_stack[tmp] = false;
cout << tmp << "-";
} while (tmp != x);
cout << endl;
}
}
void scc_tarjan()
{
for (int i = 0; i < V; i++)
if (!dfn[i])
tarjan_dfs(i);
}
int main()
{
scc_tarjan();
return 0;
}