三元环计数
三元环计数
无向图三元环计数
将无向图转化成有向图,度大的指向度小的,若度一样,按照编号排序。
枚举每个点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);
}