当前位置:   article > 正文

求无向图的三元环个数_怎么求无向图的三元组个数

怎么求无向图的三元组个数
问题描述:

给定 n n n个点, m m m条边的无向图,求三元环个数。
n ≤ 100000 , m ≤ m i n ( 200000 , n ∗ ( n − 1 ) / 2 ) n\le100000,m\le min(200000,n*(n-1)/2) n100000mmin(200000,n(n1)/2)

问题分析:

搜集到的比较好的解法主要有两种:

法一: 把边定向后枚举一条边

先按照原图的边求出每个点的度数,然后把原图的无向边改为有向边:度数小的向度数大的连边,度数相同由编号小的向编号大的连边。(其实按照度数排序就可以了,我们记 u u u排序之后的顺序为 r n k u rnk_u rnku

如果你是把边改成了有向边,那么可以保证现在每个点的出度 ≤ m \le\sqrt m m ,然后枚举一条边(u,v),然后遍历其中一个端点的邻接点打上标记,再遍历另一个端点的邻接点,遇上标记就ans++。复杂度 O ( m m ) O(m\sqrt m) O(mm )

如果你是按照度数排序,那么枚举一条边(u,v)( r n k u &lt; r n k v rnk_u&lt;rnk_v rnku<rnkv),遍历u的邻接点w ( r n k w &gt; r n k u rnk_w&gt;rnk_u rnkw>rnku),如果v与w联通,ans++。当u的度数 ≥ m \ge\sqrt m m 时,w的个数 ≤ m \le\sqrt m m 。故复杂度也是 O ( m m ) O(m\sqrt m) O(mm )的。

如果懒得把边定向,也可以直接枚举原图边,用hash表记录邻接情况(譬如边(a,b)表示成an+b和bn+a),再枚举边的度数小的端点,判断是否与另一个端点联通,每个环算了三遍,答案最后需要除以3。均摊复杂度似乎仍然是 O ( m m ) O(m\sqrt m) O(mm ),但也许会慢一些。

法二:把点按度数分类

从1~n枚举每个点x,把x的邻接点y按度数分类,并打上标记:

  • y的度数 ≤ m \le\sqrt m m ,直接枚举y的邻接点z,如果z被标记过,ans++。
    由于总共只会枚举m条xy边,所以这部分的总复杂度是 O ( m m ) O(m\sqrt m) O(mm )的。
  • y的度数 &gt; m &gt;\sqrt m >m ,继续枚举x的邻接点z,如果y和z相连,ans++。
    由于这样的y的个数 ≤ m \le\sqrt m m 个,所以枚举y的复杂度为 O ( m ) O(m) O(m),枚举z的复杂度为均摊 O ( m ) O(\sqrt m) O(m ),总复杂度似乎也是 O ( m m ) O(m\sqrt m) O(mm )。(至于枚举z的复杂度的严格证明。。感性理解

这个方法答案也要除以3。

Code:
咕掉了。。。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/64597
推荐阅读
相关标签
  

闽ICP备14008679号