三元環計數
阿新 • • 發佈:2020-10-10
三元環計數
無向圖三元環計數
將無向圖轉化成有向圖,度大的指向度小的,若度一樣,按照編號排序。
列舉每個點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); }