0
点赞
收藏
分享

微信扫一扫

tarjian算法解决强连通分量问题

小北的爹 2022-02-18 阅读 75

学习目录:1.总结tarjian算法解决强连通分量问题的相关知识。

                   2.开始复习以前的知识。

一.tarjian算法解决强连通分量

如下图(来源于biibii邋遢大哥):

代码实现如下:

#include<bits/stdc++.h>
using namespace std;
struct Edge
{
	int to,next;
}edge[500010];
int cnt,head[100010],dfn[100010],low[100010],book[100010],stackk[100010];//dfn[]:即时间戳,表示他在dfs(tarjan)中是第几个被搜到的,low[]表示该点通过有向边可回溯的最早的时间戳(dfn数组)
//链式前向星
void add(int a,int b)
{
    cnt++;
    edge[cnt].to=b;
    edge[cnt].next=head[a];
    head[a]=cnt;
}
int top,timee,ans;
void tarjan(int x)
{
    timee++;
    dfn[x]=low[x]=timee;
    top++;
    stackk[top]=x;
    book[x]=1;//标记在栈中
    for(int i=head[x];i!=-1;i=edge[i].next)
    {
        int y=edge[i].to;
        if(dfn[y]==0)//该节点未被访问过
        {
            tarjan(y);
            low[x]=min(low[y],low[x]);
        }
        else if(book[y]==1)
        {
            low[x]=min(low[y],dfn[x]);
        }
    }
    if(low[x]==dfn[x])
    {
        ans++;//ans表示有几个强连通分量
        while(stackk[top]!=x)
        {
            book[stackk[top]]=0;//标志其不在栈中
            top--;
        }
        book[stackk[top]]=0;
        top--;
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        head[i]=-1;
    int x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);//有一条从x到y的边
        add(x,y);
    }
    for(int i=1;i<=n;i++)
    if(dfn[i]==0)tarjan(i);
    printf("%d",ans);
    return 0;
}

举报

相关推荐

0 条评论