没啥好说的,唯一要注意的就是那些单独的点每个点都会被当做自身一个强联通分量,也就是有不少的强连通分量里面可能只有一个元素……直接上代码
int dfn[105],low[105],scccnt=0,sccindex=0,belong[105];
bool instack[105];
stack<int>sta;
vector<int>G[105];
void tarjan(int v)
{
dfn[v]=low[v]=++sccindex;
sta.push(v);instack[v]=true;int j;
for(auto i=G[v].begin();i!=G[v].end();i++){
int j=*i;//理论上用c++11的特性会比G[v].size()快一些;
if(!dfn[j]){
tarjan(j);
low[v]=min(low[v],low[j]);
}
else if(instack[j]&&dfn[j]<low[v])
low[v]=dfn[j];
}
if(low[v]==dfn[v]){
scccnt++;
do{
j=sta.top();instack[j]=false;
sta.pop();belong[j]=scccnt;
}while(j!=v);//一定要注意这里并不是要把整个栈清空,只是要把属于当前联通分量的元素全部清空
}
}
主函数中调用:
int n,i,j;
cin>>n;
for(i=1;i<=n;i++){
while(cin>>j&&j)
G[i].push_back(j);
}
for(i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);