Hdu 6184 三元環計數
阿新 • • 發佈:2018-12-10
題目描述 給一個2e5點2e5邊的無向圖,求子圖 { V=(A,B,C,D) E=(AB,BC,CD,DA,AC) } 的數量。 HINT 考慮把所有邊定向,從度數小的點往度數大的點連,這樣每個點的出度都小於sqrt(2e5)。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=200007; int n,m; int x[maxn],y[maxn],d[maxn]; vector<pair<int,int> >g[maxn]; int cnt[maxn],vis[maxn],id[maxn]; int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++)d[i]=0; for(int i=1;i<=n;i++)g[i].clear(); for(int i=1;i<=m;i++)cnt[i]=vis[i]=0; for(int i=1;i<=m;i++){ scanf("%d%d",&x[i],&y[i]); d[x[i]]++; d[y[i]]++; } for(int i=1;i<=m;i++){ if(d[x[i]]<d[y[i]]||(d[x[i]]==d[y[i]]&&x[i]<y[i])){ g[x[i]].push_back(make_pair(y[i],i)); } else { g[y[i]].push_back(make_pair(x[i],i)); } } ll ans=0; for(int i=1;i<=m;i++){ int u=x[i],v=y[i]; for(int j=0;j<g[u].size();j++){ vis[g[u][j].first]=i; id[g[u][j].first]=g[u][j].second; } for(int j=0;j<g[v].size();j++){ if(vis[g[v][j].first]==i){ cnt[i]++; cnt[id[g[v][j].first]]++; cnt[g[v][j].second]++; } } } for(int i=1;i<=m;i++){ ans+=1ll*cnt[i]*(cnt[i]-1)/2; } printf("%lld\n",ans); } }