有向图的强连通分量

这篇具有很好参考价值的文章主要介绍了有向图的强连通分量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有向图的强连通分量

对于一个有向图,连通分量:对于分量中任意两点u,v,必然可以从u走到v,且从v走到u.
强连通分量:极大连通分量。
求出强连通分量后,可以通过将强连通分量缩点的方式,将有向图转化成有向无环图。
求强连通分量的方法:tarjan O(n+m),时间复杂度是线性的
1 . 采用dfs来遍历整个图,可以将边分为四类 (x->y)

  • 树枝边 x是y的父节点
  • 前向边 x是y的祖先,x可以到达y
  • 后向边 y是x的祖先, x可以到达y
  • 横叉边 x可以到达已经遍历且已经回溯过的y点

2 .如何确定点在连通分量中

  • 存在一条后向边,使其指向祖先节点
  • 存在一条横插边,走过了横叉边,又存在一条后向边指向原来的点的祖先节点

3 .引入一个时间戳的概念

  • dfn[u] 表示遍历到u的时间,也就是dfs序
  • low[u] 表示从u所在强连通分量中,所能遍历到的层次最高的点的dfs序。
  • 当dfs[u]==low[u]时,表示u是其所在的强连通分量的最高点

4 . 对于tarjan算法,我的理解是每次都是对以当前的点为根节点的子图进行操作的,遍历完子图中的所有点时,如果dfs[u]==low[u]表示当前的根就是在强连通图中,一个一个清掉栈中的元素,在没有清掉当前点的时候,清理出的元素都是强连通图中的元素。


int n,m;
int h[N],ne[M],e[N],idx=0;
int dfn[N],low[N],tm=0;
int vis[N];
int id[N],cnt=0,ids[N];
int dout[N];
stack<int> s;

void add(int a,int b)
{
  e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void tarjan(int u)
{
  dfn[u]=low[u]=++tm;
  s.push(u);
  vis[u]=1;
  for(int i=h[u];~i;i=ne[i])
  {
     int j=e[i];
     if(!dfn[j])
     { 
           tarjan(j);
           low[u]=min(low[u],low[j]);
     }
     else if(vis[j]) low[u]=min(low[u],dfn[j]);
  }

   if(dfn[u]==low[u])
   {
    ++cnt;
    int y;
    do{
       y=s.top();
       s.pop();
       vis[y]=0;
       id[y]=cnt;
       ids[cnt]++;
    }while(y!=u);
   }
}

总结:使用完tarjan算法后,就已经将有向图转化为有向无环图(DAG)。
而对于有向无环图,有以下几种应用:(注意以下的点是经过缩点之后的,点代表的是一个强连通分量,其中的点的个数为非零个)

1 是否存在点能被其他所有点到达。
只需计算出度为零的点有几个:

  • 有一个的话,表示存在,个数为当前连通快的大小。
  • 有多个的话,则为零个

2 选取最少的点数,即可遍历整个图

  • 找出入度为零的强连通块数,即为答案。(强连通块中的点互相可以到达)

3 需要添加最少的边数,使整个图变为强连通分量文章来源地址https://www.toymoban.com/news/detail-497362.html

  • 当强连通块的数量为1时,不需要加边
  • 不为1时,答案为在入度为零的点个数和出度为零的点个数取最大值,因为最优情况时,每个出度为零的点向入度为零的点加一条边,反之亦然。

到了这里,关于有向图的强连通分量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 用go语言实现一个构建有向图的函数,同时图结构的点和边上都支持添加属性

    当然可以。下面是一个简单的用Go语言实现的有向图构建函数的示例。这个图结构使用map来存储,每个节点都由一个唯一的标识符(id)表示,并且节点和边都可以附加属性。 go 这个示例代码创建了一个有向图,并添加了两个节点(A和B)和一个从A到B的边。每个节点和边都有

    2024年01月20日
    浏览(7)
  • 有向图的拓扑排序

    拓扑排序 。任意给定一个有向图,设计一个算法,对它进行拓扑排序。拓扑排序算法思想:a.在有向图中任选一个没有前趋的顶点输出;b.从图中删除该顶点和所有以它为尾的弧;c.重复上述a、b,直到全部顶点都已输出,此时,顶点输出序列即为一个拓朴有序序列;或者直到

    2024年02月09日
    浏览(8)
  • 公开游戏、基于有向图的游戏

    公开游戏、基于有向图的游戏

    目录 〇,背景 一,公开游戏、策梅洛定理 1,公开游戏 2,策梅洛定理 3,非有向图游戏的公开游戏 力扣 486. 预测赢家(区间DP) 力扣 877. 石子游戏(退化贪心) 力扣 1140. 石子游戏 II(二维DP) 力扣 1406. 石子游戏 III(数列DP) 力扣 1563. 石子游戏 V(区间DP)  力扣 1686.

    2024年02月09日
    浏览(8)
  • 真题详解(有向图)-软件设计(六十二)

    真题详解(极限编程)-软件设计(六十一) https://blog.csdn.net/ke1ying/article/details/130435971 CMM指软件成熟度模型,一般1级成熟度最低,5级成熟度最高,采用更高级的CMM模型可以提高软件质量。 初始:杂乱无章。 可重复级:建立基本的项目管理过程和跟踪费用项。 已定义(确定)

    2024年02月01日
    浏览(10)
  • 2023-04-09 有向图及相关算法

    2023-04-09 有向图及相关算法

    有向图的的应用场景 社交网络中的关注 互联网连接 程序模块的引用 任务调度 学习计划 食物链 论文引用 无向图是特殊的有向图,即每条边都是双向的 改进Graph和WeightedGraph类使之支持有向图 Graph类的改动 WeightedGraph类的改动 有些问题,在有向图中不存在,或者我们通常不考

    2024年02月05日
    浏览(19)
  • 2023-8-29 有向图的拓扑排序

    2023-8-29 有向图的拓扑排序

    题目链接:有向图的拓扑排序

    2024年02月11日
    浏览(11)
  • 有向图的邻接表和邻接矩阵

    有向图的邻接表是一种常用的表示方法,用于表示图中各个节点之间的关系。在有向图中,每条边都有一个方向,因此邻接表中的每个节点记录了该节点指向的其他节点。 具体来说,有向图的邻接表由一个由节点和它们的邻居节点列表组成的集合构成。对于每个节点,邻接表

    2024年02月22日
    浏览(5)
  • 搜索与图论-有向图的拓扑序列

    搜索与图论-有向图的拓扑序列

    有向图的拓扑序列就是图的广度优先遍历的一个应用。 若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A 中都出现在 y 之前,则称 A 是该图的一个 拓扑序列 。(起点在终点的前面) 拓扑序列是针对有向图,无向图是没有拓扑序列的。 有向无环图一定是

    2024年02月01日
    浏览(6)
  • 使用颜色检测有向图中的循环

    使用颜色检测有向图中的循环

    给定一个有向图,检查该图是否包含循环。如果给定的图形至少包含一个循环,您的函数应返回 true,否则返回 false。 例子:   输入:  n = 4, e = 6  0 - 1, 0 - 2, 1 - 2, 2 - 0, 2 - 3, 3 - 3  输出: 是  解释:    

    2024年02月03日
    浏览(12)
  • 二十一、搜索与图论——拓扑序列(有向图)

    二十一、搜索与图论——拓扑序列(有向图)

    拓扑序列定义: 若一个由图中所有点构成的序列 A满足:对于图中的每条边 (x,y),x在 A中都出现在 y之前,则称 A是该图的一个拓扑序列。 人话: 始终满足每条边的起点在终点前面,从前指向后。 注意:如果在有向图中构成一个环,则必定无法构成拓扑结构,也可以证明有向

    2024年02月04日
    浏览(6)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包