题解:
考虑三个点在树上的形态:
(1)成一条链(其实就是中心是三个点中的一个点)
(2)存在一个唯一中心连接三个点,且中心到三个点的路径除了中心之外不相交
(定义自己脑补一下吧...)
显然只有在(2)情况下,并且唯一中心到三个点的路径长度相等才能满足条件.
我们直接枚举唯一中心,以其为根做有根树,则三个点必须分布在不同的子树中,且深度相同.
这个就很容易搞了,看代码搞搞就行了.
代码:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define N 5010
int head[N],next[N<<1],end[N<<1];
inline void addedge(int a,int b){
static int q=1;
end[q]=b;
next[q]=head[a];
head[a]=q++;
}
inline void make(int a,int b){
addedge(a,b);
addedge(b,a);
}
int sum1[N];
ll sum2[N];
struct Array{
int a[N],t[N],tclock;
inline int operator[](int x){
if(t[x]!=tclock){
t[x]=tclock;
a[x]=0;
}
return a[x];
}
inline void add(int x){
if(t[x]!=tclock){
t[x]=tclock;
a[x]=0;
}
++a[x];
}
}temp;
int max_dep;
inline void dfs(int x,int fa,int dep){
temp.add(dep);
max_dep=max(max_dep,dep);
for(int j=head[x];j;j=next[j])
if(end[j]!=fa)
dfs(end[j],x,dep+1);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("tt.in","r",stdin);
#endif
int n;
scanf("%d",&n);
int i,j,k,a,b;
for(i=1;i<n;++i){
scanf("%d%d",&a,&b);
make(a,b);
}
ll ans=0;
int son;
for(i=1;i<=n;++i){
memset(sum1,0,sizeof sum1);
memset(sum2,0,sizeof sum2);
for(son=1,j=head[i];j;j=next[j],++son){
++temp.tclock;
max_dep=0;
dfs(end[j],i,1);
for(k=1;k<=max_dep;++k){
if(son>=3)
ans+=sum2[k]*temp[k];
sum2[k]+=temp[k]*sum1[k];
sum1[k]+=temp[k];
}
}
}
cout<<ans<<endl;
return 0;
}