您的位置:首页 > 其它

NYOJ oj 120 强连通分量之 tarjan

2013-04-28 12:51 351 查看
#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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: