跳到主要内容

环计数

参考资料

简介

三元环计数(Triangle Counting)要求统计无向简单图中所有满足三点两两相邻的无序三元组 (u,v,w)(u,v,w) 的数量。

算法基于边定向:将每条无向边 (u,v)(u,v) 定向为从度数较小的端点指向度数较大的端点(度数相同则从编号较小指向较大)。定向后图为 DAG。枚举每个节点 uu,标记 uu 指向的所有节点,再枚举 uu 的出边邻居 vv 的出边邻居 ww,若 ww 被标记则 (u,v,w)(u,v,w) 构成三元环。时间复杂度 O(mm)O(m\sqrt{m})

实现

612 Bcpp
#include <bits/stdc++.h>
using namespace std;

const int N=100005;
int deg[N];
bool vis[N];
vector<int> G[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<pair<int,int>> edges(m);
for(auto &[u,v]:edges)
{
cin>>u>>v;
deg[u]++;deg[v]++;
}
for(auto [u,v]:edges)
{
if(deg[u]<deg[v]||(deg[u]==deg[v]&&u<v))G[u].push_back(v);
else G[v].push_back(u);
}
int ans=0;
for(int u=1;u<=n;u++)
{
for(auto v:G[u])vis[v]=1;
for(auto v:G[u])
{
for(auto w:G[v])
{
if(vis[w])ans++;
}
}
for(auto v:G[u])vis[v]=0;
}
cout<<ans<<'\n';
return 0;
}

例题

无向图 GG 的三元环指的是一个 GG 的一个子图 G0G_0,满足 G0G_0 有且仅有三个点 u,v,wu, v, w,有且仅有三条边 u,v,v,w,w,u\langle u, v\rangle,\langle v, w\rangle,\langle w, u\rangle。两个三元环 G1,G2G_1, G_2 不同当且仅当存在一个点 uu,满足 uG1u\in G_1uG2u\notin G_2