该说的都在代码里了,老师给的模板不符合本菜鸡的要求啊只能手动扩充了,用的是邻接矩阵存储图,可以换成邻接表啥的可能快点
#include <iostream>
#include<stack>
#include<string.h>
using namespace std;
#define MAXL 1000
/*
例子:
6
7
0 1
0 4
0 5
1 2
2 3
3 0
4 0
*/
/*
例子:
8
10
0 1
1 2
2 3
2 1
3 0
0 4
0 5
5 6
6 7
7 5
*/
int d[MAXL], L[MAXL],visited[MAXL];
int index;//访问顺序
int s[MAXL];//栈
int t,Size;//栈顶和边的最大值
int edge[MAXL][MAXL];//邻阶矩阵存储边
int min(int a, int b) {
return a > b ? b : a;
}
void tarjan(int u) {
if (visited[u]) {//已经访问过就跳过
return;
}
d[u] = L[u] = ++index;//初次访问设置
s[t++] = u;//存入栈
visited[u] = 1;//标记访问(不需要在函数末尾恢复0)
for (int i = 0; i < Size; i++) {//遍历始点为u的边
if (edge[u][i]) {//有这条边
if (!visited[i]) {//这条边的终点已经访问过就没用,没访问过则进行深搜
tarjan(i);
L[u] = min(L[u], L[i]);
}
else {
L[u] = min(L[u], d[i]);
}
}
}
if (d[u] == L[u]) {//找到一个强连通分支始点(即DFS最早访问的点)后输出
cout<<"帅:"<<endl;
int out0 = -1;
out0 = s[--t];
if (out0 == u) {
cout << out0 << endl;
}
else {
while (out0 != u) {
out0 = s[t--];
cout << out0 << " ";
}
cout << endl;
}
}
}
int main()
{
cin >> Size;//顶点数
memset(d, 0, sizeof(d));
memset(L, 0, sizeof(L));
memset(s, 0, sizeof(s));
memset(edge, 0, sizeof(edge));
memset(visited, 0, sizeof(visited));
int m, a, b;
cin >> m;
while (m--) {
cin >> a >> b;
edge[a][b] = 1;
}
for (int i = 0; i < Size; i++) {
tarjan(i);//全部访问查找
}
}