NYOJ oj 120 强连通分量之 tarjan

#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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值