#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#define MAX 500
using namespace std;
int top,bet,indx,cont=0;
vector <int> vc[MAX];
bool DFN[MAX],stack[MAX];
int dfn[MAX],instack[MAX],low[MAX];
void tarjan(int x)
{
int y;
dfn[x] = low[x] = ++indx;
DFN[x] = stack[x] = true;
instack[++top] = x;
for(int i=0;i<vc[x].size();i++)
{
y = vc[x][i];
if(!DFN[y])
{
tarjan(y);
low[x] = min(low[x],low[y]);// 当形成环的时候,更新每个节点的值
}
else
if(stack[y])
{
low[x] = min(low[x],dfn[y]);// 使得每个环中最后一个节点,更新成他们的 根节点
}
}
if(dfn[x]==low[x])
{ // 每执行一次,便是一个强连通分量
++bet;
do
{
y = instack[top--];
stack[y]=false;
}while(x!=y);
}
}
int main()
{
int N,n,m;
scanf("%d",&N);
while(N--)
{
scanf("%d",&n);
indx = 0,bet = 0,top = 0;
memset(dfn,0,sizeof(dfn)); // 记录访问的次数
memset(instack,0,sizeof(instack));
memset(low,0,sizeof(low)); // 一个强连通分量中的 所有值都更新成他们得得根节点
memset(stack,false,sizeof(stack)); //记录是否在栈中
memset(DFN,false,sizeof(DFN));
memset(vc,0,sizeof(vc));
for(int i=1;i<=n;i++)
{
while(scanf("%d",&m),m)
{
vc[i].push_back(m);
}
}
tarjan(1);
printf("%d\n",bet-1);
}
}
NYOJ oj 120 强连通分量之 tarjan
最新推荐文章于 2020-01-04 16:34:46 发布