传送:
https://vjudge.net/problem/Kattis-gottacatchemall
前置知识:
三元环计数 https://www.cnblogs.com/Dance-Of-Faith/p/9759794.html
思路:
首先去重边,记每个点的度数为n,三元环个数为m,答案为(∑n*(n-1))-6*m。记得开long long。
code:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef pair<int,int> P; 5 const int N=300000+10; 6 int head[N],ver[N],nex[N],tot=1; 7 inline void add(int x,int y) 8 { 9 ver[++tot]=y; 10 nex[tot]=head[x]; 11 head[x]=tot; 12 } 13 14 P e[N]; 15 int deg[N],v[N]; 16 17 bool cmp(const P &t) 18 { 19 return deg[t.first]==deg[t.second]?t.first<t.second:deg[t.first]>deg[t.second]; 20 } 21 22 int main() 23 { 24 int n,cnt=0; 25 scanf("%d",&n); 26 for(int i=1; i<n; ++i) 27 { 28 int x,y; 29 scanf("%d%d",&x,&y); 30 e[cnt++]=make_pair(min(x,y),max(x,y)); 31 } 32 sort(e,e+cnt); 33 cnt=unique(e,e+cnt)-e; 34 for(int i=0;i<cnt;++i) 35 { 36 ++deg[e[i].first]; 37 ++deg[e[i].second]; 38 } 39 for(int i=0;i<cnt;++i) 40 { 41 if(cmp(e[i])) 42 add(e[i].first,e[i].second); 43 else add(e[i].second,e[i].first); 44 } 45 ll ans=0,c=0; 46 for(int i=1;i<=n;++i) 47 { 48 int t=deg[i]; 49 if(t)ans+=(ll)t*(t-1)/2; 50 for(int j=head[i];j;j=nex[j]) 51 v[ver[j]]=i; 52 for(int j=head[i];j;j=nex[j]) 53 for(int k=head[ver[j]];k;k=nex[k]) 54 if(v[ver[k]]==i)++c; 55 } 56 printf("%lld\n",2*ans-6*c); 57 return 0; 58 }