这个算法我也不太懂,,看着伪代码,就把这个算法的模板给写出来了。。。
以后有机会再深入研究吧,这个学习态度,自己一下
代码:
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=1001;
bool inStack[maxn]; //判断是否在栈中
int dfn[maxn]; //dfn表示深度遍历时的访问次序
int low[maxn]; //low表示可以回到的最小次序处
int stap[maxn]; //存储遍历过的点,便于在找到强连通分量时输出
int numVertex,numRoad,numAdj,index,stop; //顶点数、路数、连通分量数、访问次序、控制输出的量
vector<int> myV[maxn]; //存储有向图
void storeMap()
{
for(int j=0;j<maxn;j++)
{
myV[j].clear();
}
int from,to;
for(int i=0;i<numRoad;i++)
{
scanf("%d%d",&from,&to);
myV[from].push_back(to);
}
}
void tarjan(int i) //tarjan算法
{
int j;
dfn[i]=low[i]=++index; //深度遍历的访问次序
inStack[i]=true; //访问到就相当于进栈
stap[++stop]=i; //利用stap[]记录栈中的点,当找到连通分量时输出和删除
for(int k=0;k<myV[i].size();k++) //一点一点的向下深度遍历
{
j=myV[i][k]; //取出当前和i相邻的点j
if(!dfn[j]) //j没被访问过才访问,否则会重复求解连通分量
{
tarjan(j);
low[i]=(low[i]>low[j])?low[j]:low[i];
}
else if(inStack[j] && dfn[j]<low[i])
{
low[i]=dfn[j];
}
}
if(dfn[i]==low[i])
{
numAdj++;
printf("The %dth Connected Component:\n",numAdj);
do
{
j=stap[stop--];
printf("%d ",j);
inStack[j]=false;
}while(i!=j);
printf("\n");
}
}
void solve()
{
//初始化条件
memset(dfn,0,sizeof(dfn));
memset(inStack,false,sizeof(inStack));
numAdj=index=stop=0;
for(int i=1;i<=numVertex;i++) //从所有点出发找连通分量
{
if(!dfn[i]) //点i之前没出现过,否则就会重复找
{
tarjan(i);
}
}
}
int main()
{
while(scanf("%d%d",&numVertex,&numRoad)==2)
{
storeMap();
solve();
printf("The Sum Of Connected Component Is : %d\n",numAdj);
}
system("pause");
return 0;
}
测试实例:
1、图形
2、输入及结果