思路:显然这样结构的图像能够转化为三元环来作。c++
咱们用一个数组 v i s vis vis来维护每条边是否在三元环里。数组
咱们能够经过枚举每条边是三元环的边的次数来计算出该边对答案的贡献。ide
c o n t r i b u t i o n = c n t [ i ] × ( c n t [ i ] − 1 ) 2 contribution=\dfrac{cnt[i]\times(cnt[i]-1)}{2} contribution=2cnt[i]×(cnt[i]−1)。spa
时间复杂度: O ( m m ) O(m\sqrt{m}) O(mm )。code
m m m取 1 e 5 1e5 1e5的话,时间复杂度大约在 3 e 7 3e7 3e7左右。blog
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7; #define mst(a) memset(a,0,sizeof a) #define lx x<<1 #define rx x<<1|1 #define reg register #define PII pair<int,int> #define fi first #define se second int n,m,deg[N],cnt[N<<1],vis[N]; PII a[N<<1]; vector<PII>e[N]; int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=m;i++){ scanf("%d%d",&a[i].fi,&a[i].se); deg[a[i].fi]++,deg[a[i].se]++; } for(int i=1;i<=m;i++){ int u=a[i].fi,v=a[i].se; if(deg[u]>deg[v]||deg[u]==deg[v]&&u>v) swap(u,v); e[u].push_back({v,i}); } for(int u=1;u<=n;u++){ for(auto v:e[u]) vis[v.fi]=v.se; for(auto v:e[u]) for(auto w:e[v.fi]) if(vis[w.fi]) cnt[v.se]++,cnt[w.se]++,cnt[vis[w.fi]]++; for(auto v:e[u]) vis[v.fi]=0; } ll ans=0; for(int i=1;i<=m;i++){ ans+=1LL*cnt[i]*(cnt[i]-1)/2; cnt[i]=0; } printf("%lld\n",ans); for(int i=1;i<=n;i++) e[i].clear(),deg[i]=0; } return 0; }