关于强连通分量浅谈

本文介绍了强连通分量的概念,由Robert Tarjan提出的求解算法,并通过DFS进行详细解释。文章探讨了无向图中的强连通分量、割桥和割点,提供了相应的代码示例。
摘要由CSDN通过智能技术生成

强连通分量由美国计算机科学家 Robert Tarjan 提出。

Tarjan

职业:计算机科学家

主要成就:设计了求解的应用领域的许多问题的广泛有效的算法和数据结构等,1986年获得图灵奖.

简介:Robert Tarjan,计算机科学家,以LCA、强连通分量等算法闻名。他拥有丰富的商业工作经验,1985年开始任教于普林斯顿大学。

事实上上述并没有什么用。如果真的想知道就上百度百科吧。

一个很好的图论工具

分割线


普及几个强连通分量的定义

强连通: 在一个有向图G里,设两个点 a b 发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通

强连通图: 如果 在一个有向图G中,每两个点都强连通,我们就叫这个图为强连通图。

强连通分量:在一个有向图G中,有一个子图,这个子图每2个点都满足强连通,我们就叫这个子图叫做 强连通分量


1.现在是有向图的Tarjan。

先来看个图。

由上述定义知:

子图1,2,3构成一个强连通。

点4独立为一个强连通。

点5也是一个独立的强连通。

相信现在的你已经知道强连通分量究竟是什么了。

然而一个重要的问题产生了:

怎么求它呢???


dfs

那么怎么dfs呢?

首先需要三个数组:

1.dfn[Max];(存储时间戳)

2.low[Max];(存储在它之前的最小时间戳)

3.cast[Max];(标记它所在的强连通)

还是刚才的图。

开始时dfn==low;

从1开始(入栈),先搜点2(入栈);

点2再搜点3(入栈),点3搜到了点1,这是点1正在栈中(更新点3的low值;

回溯更新点2的low,再回溯更新点1的low(当然还是原来的low,点1的dfn==low;

此时1搜到4(入栈),点4搜到点5;

点5开始纠结,因为他搜不到别人了,只好老老实实的被使用自己的low;

于是点5的dfn==low成为了一个强连通(出栈);cast[5]=1;

点4也由于点5的low影响不到他,dfn==low,也成为了一个强连通(出栈)。cast[4]=2;

回溯到点1,发现点5已经被访问,而且已经出栈,便不用理他。

此时dfn[1]==low[1]。

开始大批出栈

1出栈,2出栈,3出栈。cast全为3;

成功

那么看一段代码吧:

void tarjan(int x)
{
   
    s.push(x);
    ins[x]=1;
    inx++;
    dfn[x]=low[x]=inx;
    for(int i=head[x];i!=-1;i=e[i].next)
    {
   
        if(dfn[e[i].to]==0)
        {
   
            tarjan(e[i].to);
            low[x]=min(low[x],low[e[i].to]);
        }
        else if(ins[e[i].to]==1)low[x]=min(low[x],dfn[e[i].to]);
    }
    int v=100000;
    if(dfn[x]==low[x])
    {
   
        gs++;
        while(x!=</
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值