有向图强连通算法

这里推荐一个很好的讲解网页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;
	}
}


你可能感兴趣的:(有向图强连通算法)