Loading

三元环计数

三元环计数

参考博客

洛谷模板

无向图三元环计数

将无向图转化成有向图,度大的指向度小的,若度一样,按照编号排序。

枚举每个点x,将x的所有相邻点标记,然后枚举x的相邻点y,再枚举y的相邻点z,
如果z已经被标记,那么(x,y,z)就是如图示的三元环。

复杂度 : \(O(n\sqrt n)\)

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

#define rep(i,a,b) for(int i = a;i <= b;i++)
#define repE(i,u) for(int i = head[u];i;i = E[i].next)

int n, m;

const int N = 1e5 + 10;
const int M = 2e5 + 10;

struct Edge {
	int to, next;
}E[M];
int head[N], tot;
void addEdge(int from, int to) {
	E[++tot] = Edge{ to,head[from] };
	head[from] = tot;
}
int deg[N], s[M], t[M];
int vis[N];

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d", s + i, t + i); deg[s[i]]++; deg[t[i]]++;
	}
	for (int i = 0; i < m; i++) {
		int u = s[i], v = t[i];
		if (deg[u] == deg[v] and u < v)swap(u, v);
		if (deg[u] < deg[v])swap(u, v);
		addEdge(u, v);
	}
	int ans = 0;
	rep(u, 1, n) {
		repE(i, u) vis[E[i].to] = u;
		repE(i, u) {
			int to = E[i].to;
			repE(j, to) {
				int v = E[j].to;
				if (vis[v] == u) {
					ans++;
				}
			}
		}
	}
	printf("%d\n", ans);
}
posted @ 2020-10-10 19:09  —O0oO-  阅读(107)  评论(0编辑  收藏  举报