tarjan(u){
DFN[u]=Low[u]=++Index // 为节点u设定次序编号和Low初值
Stack.push(u) // 将节点u压入栈中
for each (u, v) in E // 枚举每一条边
if (v is not visted) // 如果节点v未被访问过
tarjan(v) // 继续向下找
Low[u] = min(Low[u], Low[v])
else if (v in S) // 如果节点u还在栈内
Low[u] = min(Low[u], DFN[v])
if (DFN[u] == Low[u]) // 如果节点u是强连通分量的根
repeat v = S.pop // 将v退栈,为该强连通分量中一个顶点
print v
until (u== v)
}
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
vector<int> v[100];
stack<int> stk;
int DFN[100],LOW[100];
int index;
bool vis[100];
void TarJan(int u)
{
DFN[u]=LOW[u]=++index;
stk.push(u);
vis[u]=true;
for(int w:v[u])
{
if(!DFN[w])
{
TarJan(w);
LOW[u]=min(LOW[u],LOW[w]);
}
else if(vis[w]) LOW[u]=min(LOW[u],DFN[w]);
}
if(DFN[u]==LOW[u])
{
int s;
do{
s=stk.top();
stk.pop();
cout<<s<<" ";
vis[s]=false;
}while(u!=s);
cout<<endl;
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;++i)
{
int s,e;
cin>>s>>e;
v[s].push_back(e);
}
for(int i=1;i<=n;++i)
{
if(!DFN[i]) TarJan(i);
}
return 0;
}