Tarjan算法_模板

只是下一下模板,如果还是没有懂得原理的,可以看一下这位大牛的博客:https://blog.csdn.net/qq_34374664/article/details/77488976

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN = 1100;
struct Node
{
    int next1,c;
}edge[MAXN];
int head[MAXN];
int dfn[MAXN],low[MAXN];
int vis[MAXN],stact[MAXN];
int tot,cnt,index;

void add(int xx,int y)     //前向星
{
    edge[++cnt].next1 = head[xx];
    edge[cnt].c = y;
    head[xx] = cnt;
}

void Tarjan(int x)
{
    dfn[x] = low[x] = ++tot;   //这里也不可以是0,因为0表示还没有开始深搜,要从1开始
    vis[x] = 1;stact[++index] = x;//注意这里的stact中的0位置是什么都不能储存的,因为后面要去判断栈中直到某一个数全部输出,所以要到达他的后一个位置,所以不能是0
    for(int i = head[x];i != -1; i = edge[i].next1)//找到这个点的全部变
    {
        int v = edge[i].c;
        if(!dfn[v])     //如果还没有深搜过这个点
        {
            Tarjan(v);
            low[x] = min(low[x],low[v]);
        }
        else if(vis[v]) //如果这个点已经在栈中了,那么正在遍历的这个点的low就要指向他的父亲节点,也就是小的那个
            low[x] = min(low[x],dfn[v]); //比较谁是谁的儿子
    }
    if(low[x] == dfn[x])   //表示在x之后在都在一个连通分量里面,所以要全部输出
    {
        do{
            printf("%d ",stact[index]);
            vis[stact[index]] = 0;
            index -- ;
        }while(x != stact[index+1]);
        printf("\n");
    }
    return ;

}

int main()
{
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(vis,0,sizeof(vis));
    memset(stact,0,sizeof(stact));
    tot=0;cnt=0;index=0;
    int n,m;
    scanf("%d%d",&n,&m);
    int xx,y;
    for(int i = 1;i <= m;i ++)
    {
        scanf("%d%d",&xx,&y);
        add(xx,y);
    }
    for(int i = 1; i <= n;i ++)
        if(!dfn[i])
            Tarjan(i);
    return 0;
}
关于Tarjan算法的应用有很多,后面争取尽快整理出来,不光光只是模板......
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值