bool GraphList::FindSCC(int index, int *dfn, int *low, int &tStamp, stack<int> &aStack){
dfn[index] = low[index] = ++tStamp;
this->mark[index] = DISCOVERED; //DISCOVERED
aStack.push(index);
//遍历相邻结点
for(Edge e = FirstEdge(graList[index].vertexId); e.to >= 0; e = NextEdge(e)) {
int j = this->id2index[e.to];
if(mark[j] == UNVISITED) { //UNVISITED没有访问过
FindSCC(j, dfn, low, tStamp, aStack);
if(low[j] < low[index]) { //树边传递low值
low[index] = low[j];
}
}
else if(mark[j] == DISCOVERED && dfn[j] < low[index]) {
low[index] = dfn[j];
}
}
//回溯
if(dfn[index] == low[index]) {
set<int> aSCC;
int top;
do{
top = aStack.top();
aStack.pop();
aSCC.insert(top);
mark[top] = FINISHED;
}while(top != index);
this->vecSCC.push_back(aSCC);
}
return true;
}
bool GraphList::FindSCC(){
RmSelfcirles();
vecSCC.clear();
int *dfn = new int[this->numVertex + 1];
int *low = new int[this->numVertex + 1];
if(!dfn || !low) {
cerr << "GraphList::RmCirlesTarjan: Memery alocate fail!" << endl;
return false;
}
int tStamp = 0;
memset(dfn, 0, numVertex * sizeof(int));
memset(low, 0, numVertex * sizeof(int));
for(int i = 0; i < this->numVertex; i ++){
this->mark[i] = UNVISITED;
}
for(int i = 0; i < this->numVertex; i ++) {
id2index[this->graList[i].vertexId] = i;
}
stack<int> aStack;
for(int i = 0; i < this->numVertex; i ++){
if(this->mark[i] == UNVISITED) {
FindSCC(i, dfn, low, tStamp, aStack);
}
}
for(unsigned i = 0; i < this->vecSCC.size(); i ++){
cout << "强连通分量" << i + 1 << ":" << endl;
set<int> aSCC = vecSCC[i];
for(set<int>::iterator iter = aSCC.begin(); iter != aSCC.end(); iter ++) {
cout << *iter << "\t";
}
cout << endl;
}
delete []dfn;
delete []low;
return true;
}