无向图三元环计数

无向图的三元环的定义

无向图 \(G\) 的三元环指的是一个 \(G\) 的一个子图 \(G_0\),满足 \(G_0\) 有且仅有三个点 \(u, v, w\),有且仅有三条边 \(\langle u, v \rangle, \langle v, w \rangle, \langle w, u \rangle\)。两个三元环 \(G_1, G_2\) 不同当且仅当存在一个点 \(u\),满足 \(u \in G_1\)\(u \notin G_2\)

P1989 无向图三元环计数

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

考虑转换成有向图,度数小的点连向度数大的点,度数一样则从编号小连到编号大的点,然后再找三元环
时间复杂度\(O(m\sqrt m)\)

#include<bits/stdc++.h>
#define cs const
#define il inline
#define ri register
#define pc(i) putchar(i)
using namespace std;
il void read(int &as)
{
	as=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') as=(as<<3)+(as<<1)+(ch^48),ch=getchar();as*=f;
}
void wt(int x){if(x<0) x=-x,pc('-');if(x>9) wt(x/10);pc(x%10|48);}
cs int N=2e5+7;
struct node{int to,nxt;}e[N];
int n,m,eoe,ans,h[N],r[N][2],deg[N],tag[N];
il void add(cs int u,cs int v){e[++eoe]={v,h[u]},h[u]=eoe;}
signed main()
{
	read(n),read(m);
	for(ri int i=1;i<=m;++i)
		read(r[i][0]),read(r[i][1]),
		deg[r[i][0]]++,deg[r[i][1]]++;
	for(ri int i=1;i<=m;++i)
	{
		int Min=deg[r[i][0]]<deg[r[i][1]]?0:1;
		if(deg[r[i][0]]==deg[r[i][1]]) Min=r[i][0]<r[i][1]?0:1;
		add(r[i][Min],r[i][Min^1]);
	}
	for(ri int u=1;u<=n;++u)
	{
		for(ri int j=h[u];j;j=e[j].nxt) tag[e[j].to]=u;
		for(ri int i=h[u];i;i=e[i].nxt)
			for(ri int j=h[e[i].to];j;j=e[j].nxt)
				if(tag[e[j].to]==u) ans++;
	}
	wt(ans);
	return 0;
}

参考 https://www.luogu.com.cn/blog/fusu2333/solution-p1989

posted @ 2023-02-02 18:32  Bertidurlah  阅读(86)  评论(0)    收藏  举报