zoukankan      html  css  js  c++  java
  • 如何将无向图变为点/边双连通,如何将有向图变为强连通图

     将无向图变为点-双连通的图

      定义:点-双连通指的是任意两个之间存在至少两条点不重复的路径

      分为两种情况, 一种是连通图,一种是非连通图

      ①连通图

        首先,找出图中的所有点-双连通分量,然后将该分支缩成一个点, 因为双连通分量内部肯定不用考虑的。

        只需要考虑双连通分量与外部的其它结点,如何加边才能形成点-双连通分量。

        

        上图的结点2,3,4,5构成了一个点-双连通分支,我们进行缩点,得到下面的图

        

      可以知道,缩点之后的图是一棵树(因为环都被缩成一个点了嘛)

      那么问题就转化为了,如果将一棵树变为点-双连通的图。

      树这种特殊的结构,只要在叶子结点之间加边,那么就可以使得任意两点存在两条点不重复的路径了。

      如果只有一个叶子结点,那么只要连一条边到根结点

      如果有两个叶子结点,那么只要两个叶子结点之间连一条边即可。

      如果有三个叶子结点a,b,c, 那么只要在a,b之间连一条边,b,c之间连一条边即可

      所以叶子结点有cnt_leaf, 那么只要加(cnt_leaf+1)/2条边

      ②非连通图

      对于非连通图,每个连通分量要变成点-双连通分量,那么方法和上面一样。

      那么只有一个问题,如果使两个点-双连通分量变成一个。

      同样的,将点-双连通分量看成一个点, 那么两个点要变成点-双连通,那么只要加2条边就行了

      

      将无向图变为边-双连通的图

       定义:任意两点存在至少两条边不重复的路径。

       同样分为两种情况, 一种是连通图,一种是非连通图   

      ①连通图

        同上

      ②非连通图

        同上

      将有向图变为强连通图

       定义:任意两点都可以相互到达的有向图叫做强连通图

      

       ①连通图

        同样的,找出所有的强连通分量, 然后缩成一个点,然后统计缩点之后的新图的出度为0的点的个数(记为cntOut),和入度为0的点的个数(记为cntIn)

        那么要加边的条数就是max(cntOut,cntIn)  

        这个为什么呢?? 因为,如果一个点的入度为0,那么说明这个点是不可达的,如果一个点的出度为0,那么说明这个点到其它点是不可达的。

        为了解决这个情况,那么只要在出度为0的点(设为u)和入度为0的点之间连一条u-->v的边,那么就解决了这种情况。

        不断的连边,只要一个点问题没解决就要连边, 所以是在两者之间取max

       ②非连通图

        对于每个连通的分支之间,按照上面的方法变成强连通分量。

        至于两个连通分量之间,连一条你指向我的边,再连一条我指向你的边就行了。

  • 相关阅读:
    Flutter子组件调用父组件方法修改父组件参数
    Flutter点击两次返回键退出APP
    Flutter路由跳转父级页面向子页面传参及子页面向父级页面传参
    Flutter中用ListView嵌套GridView报错异常
    前端项目统一 ESlint 规则集
    前端规范
    手写防抖(Debouncing)和节流(Throttling)
    手写promise进阶版本
    实现一个call或 apply
    实现一个JSON.stringify()
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4678192.html
Copyright © 2011-2022 走看看