#根号分治#洛谷 1989 【模板】无向图三元环计数

题目

给定一个 \(n\) 个点 \(m\) 条边的简单无向图,求其三元环个数。


分析

按照点度数为第一关键字编号为第二关键字从小到大排序,给无向图定向。

那么每个三元环都能被新的有向无环图包含,在这个有向无环图直接枚举出边计数

可以发现出边最多只有 \(\sqrt{m}\),度数小于等于它时显然,否则出去的点度数都大于它最多根号个

那么第三层复杂度就是根号的,所以就是 \(O(m\sqrt{m})\)


代码

#include <iostream>
#include <vector>
using namespace std;
const int N=200011;
vector<int>G[N];
int n,m,x[N],y[N],v[N],deg[N],ans;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
    cin>>n>>m;
	for (int i=1;i<=m;++i){
		cin>>x[i]>>y[i];
		++deg[x[i]],++deg[y[i]];
	}
	for (int i=1;i<=m;++i){
		if (deg[x[i]]>deg[y[i]]||(deg[x[i]]==deg[y[i]]&&x[i]>y[i])) swap(x[i],y[i]);
		G[x[i]].push_back(y[i]);
	}
	for (int x=1;x<=n;++x){
		for (int y:G[x]) v[y]=x;
		for (int y:G[x])
		for (int z:G[y])
			if (v[z]==x) ++ans;
	}
	cout<<ans;
	return 0;
}
posted @ 2026-08-12 20:01  lemondinosaur  阅读(12)  评论(0)    收藏  举报