#根号分治#洛谷 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;
}

浙公网安备 33010602011771号