兮水的博客

无向图三元环计数

兮水XiShui丶·2022-04-28 11:11·213 次阅读

无向图三元环计数

本篇博客参考这篇博客,然后根据自己的理解补了一点小细节,如果想看原文可以去这里


题意#

给定一张简单无向图,请求出图中的三元环个数,其中三元环的定义是一个三元组(i,j,k),其中(i,j),(j,k),(k,i)均有边直接相连

做法#

首先对所有边进行定向,对于任何一条边,从度数小的边连向度数大的边,如果度数相同,则从编号小的边连向编号大的边.
注意这里的度数是指无向图中的度数,也就是一条边同时会给这条边的两个端点增加度数

然后我们通过这种方法就能得到一张有向无环图,我们枚举每个点u,然后将在有向图u能直接到达的边标记为被u访问过,然后再枚举所有u在有向图能直接到达的点w,如果w相邻的点中有一个点vu访问过,那么这就是一个三元环

证明#

有向无环#

首先证明我们得到的图是一张有向无环图

如果在我们定向后的图中存在环,那么在原来的无向图中这个也一定是个环.我们假设一个环为(1>2>3>1),那么按照我们的连边规则,那么会有

deg[1]>=deg[2]>=deg[3]>=deg[1]

发现这个不等式成立时只有deg[1]=deg[2]=deg[3]这一种情况,但是当度数相等时我们按照编号大小连边,又因为1<2<3<1这个不等式显然不成立,所以这个环无论如何都不会存在

综上,这张图有向,而且没有环,所以是一张有向无环图(嗯

时间复杂度#

我们会枚举所有点,并且把所有枚举到的点都打上能到达的标记,所以复杂度为O(n+m)

然后我们考虑枚举一个点能到的所有点再枚举它能到的所有点,这个本质上是枚举i=1nouti

首先考虑当outvm的情况,因为u>v有一条边,所以degudegv,而这种点的数量显然不超过m数量级,所以这部分的复杂度为O(nm)

然后考虑当outvm时的情况,,因为u>v有一条边,所以degudegv,而这种点的数量显然不超过m数量级,所以这部分的复杂度为O(mm)

综上,时间复杂度为O(max(n,m)logm)

代码#

Copy
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
vector<int> g[N];
int deg[N], vis[N], n, m, ans;
struct E { int u, v; } e[N * 3];
int main() {
scanf("%d%d", &n, &m);
for(int i = 1 ; i <= m ; ++ i) {
scanf("%d%d", &e[i].u, &e[i].v);
++ deg[e[i].u], ++ deg[e[i].v];
}
for(int i = 1 ; i <= m ; ++ i) {
int u = e[i].u, v = e[i].v;
if(deg[u] < deg[v] || (deg[u] == deg[v] && u > v)) swap(u, v);
g[u].push_back(v);
}
for(int x = 1 ; x <= n ; ++ x) {
for(auto y: g[x]) vis[y] = x;
for(auto y: g[x])
for(auto z: g[y])
if(vis[z] == x)
++ ans;
}
printf("%d\n", ans);
}
posted @   兮水XiShui  阅读(213)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
目录