四元环计数

想看就看吧
f o r ( u ) for(u) for(u)
f o r ( v : o u t u ) for(v : out _u) for(v:outu)
f o r ( w : a d j v ) for(w : adj_v) for(w:adjv)
a n s + = c n t [ w ] + + ans += cnt[w] ++ ans+=cnt[w]++

我们把无向图按度数从小往大连边,那么每个点的度数 o u t u < = O ( m ) out_u<=O(\sqrt m) outu<=O(m )
所以上面的过程是 O ( m m ) O(m\sqrt m) O(mm )的,至于他不重不漏,好像是有序的所以不重不漏。
如果要统计经过每个点的四元环个数。
f o r ( u ) for(u) for(u)大括号内后面再加上:
f o r ( v : o u t u ) for(v : out _u) for(v:outu)
f o r ( w : a d j v ) for(w : adj_v) for(w:adjv)
r e t [ v ] + = − − c n t [ w ] ret[v] += --cnt[w] ret[v]+=cnt[w]

代码:

#include<bits/stdc++.h>
const int kN=1e5+5,MOD=1e9+7;
int n,m,a[kN],deg[kN];
long long s[kN],t[kN];
std::vector<int>e[kN];
#define G for(int y:e[x])if(great(x,y))for(int z:e[y])if(great(x,z))
inline bool great(int x,int y){return deg[x]!=deg[y]?deg[x]>deg[y]:x>y;}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    for(int i=1;i<=m;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
        ++deg[u],++deg[v];
    }
    for(int x=1;x<=n;++x){
        G s[x]+=t[z],s[y]+=t[z],s[z]+=t[z]++;
        G s[y]+=--t[z];
    }//s[i] : the number of cir4 containing point i
    return 0;
}