这里推荐一个很好的讲解网页http://blog.csdn.net/justlovetao/article/details/6673602,所以我就不说了,附上个人代码,自认为比他个精简一些。
个人代码:
#include <iostream>
#include <cstdio>
#include <cstring>
const int N = 100;
using namespace std;
struct Edge{
int id, next;
}edg[N * N];
int nod[N], key;
int LOW[N], DFN[N];//分别记录追溯到栈中最早的点和搜索的标号
int stack[N] , top;//栈
bool instack[N];//是否在栈中
int Index, number, belong[N];//number记录强联通分量个数,belond记录属于哪个强联通
void Tarjan(int key){
int k;
stack[++ top] = key;
LOW[key] = DFN[key] = ++ Index;
instack[key] = true;
for(int i = nod[key]; i != -1;i = edg[i].next){
int v = edg[i].id;
if(!DFN[v]){
Tarjan(v);
LOW[key] = min(LOW[key], LOW[v]);
}
else
if(instack[v])
LOW[key] = min(LOW[key], LOW[v]);
}
if(LOW[key] == DFN[key]){
number ++;
do{
k = stack[top --];
instack[k] = false;
belong[k] = key;
}while(k != key);
}
}
void addedg(int x, int y){
edg[key].id = y;
edg[key].next = nod[x];
nod[x] = key ++;
}
void solve(int n){
for(int i = 1;i <= n; i ++){
if(!DFN[i]){
Tarjan(i);
}
}
}
int init(){
memset(DFN, 0, sizeof(DFN));
Index = top = number = key = 0;
memset(nod, -1, sizeof(nod));
int n, m, x, y;
cin >> n >> m;
for(int i = 0; i < m; i ++){
cin >> x >> y;
addedg(x, y);
}
return n;
}
int main(){
//freopen("/home/xishuai/1.txt", "r", stdin);
int T; cin >> T;
while(T --){
int n =init();
solve(n);
for(int i = 1;i <= n;i ++)
cout << i << " " << belong[i] << endl;
}
}