tarjan模板完整版

https://www.luogu.org/problem/P2863

#include<cstdio>
#include<vector>
using namespace std;
int dfn[10005],low[10005],stack[10005],scc[10005],num[10005],vis[10005];
int clock,scc_cnt,top;
vector<int>e[10005];
inline void dfs_scc(int x)
{
    dfn[x]=low[x]=++clock;//访问次序标记;x能到的祖先中节点编号最小的 
    stack[++top]=x;//把走过的节点入栈 
    vis[x]=1;
    for(int i=0;i<e[x].size();i++)
    {
        int now=e[x][i];
        if(!dfn[now])//如果没有被访问过 
        {
            dfs_scc(now);//进它 
            low[x]=min(low[x],low[now]);//既然now是x的子节点,那么他们一定有公告的祖先,取个小的 
        } 
        else
        if(vis[now])//如果他还没有被其他强连通分量使用 
        low[x]=min(low[x],dfn[now]);//那么再小一点 
    }
    if(low[x]==dfn[x])
    {
        scc_cnt++;
        while(stack[top]!=x)
        {
        //x节点在栈中夹着的节点就是强连通分量的节点 
            scc[stack[top--]]=scc_cnt;
            vis[stack[top+1]]=0;
            num[scc_cnt]++;
        }//哪一个点在当前编号为scc_cnt的强连通分量里 
        top--;
        vis[x]=0;
        num[scc_cnt]++;
        scc[x]=scc_cnt;//一个强连通分量 
    } 
} 
int main()
{
    int n,m,a,b;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        e[a].push_back(b);
        //e[b].push_back(a);
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(dfn[i]==0)
        {
            dfs_scc(i);
        }
    }
    for(int i=1;i<=scc_cnt;i++)
    {
        if(num[i]>1)
        {
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}
全部评论

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务