有一個樹形結構,每條邊的長度相同,任意兩個節點能夠相互到達。選3個點。兩兩距離相等。有多少種方案?c++
1≤n≤5 000git
參照小塘空明的題解。post
很明顯到一個點距離相等的三個點兩兩之間距離相等。spa
因此咱們枚舉該點,對子樹進行暴力統計,注意統計的順序code
時間複雜度\(O(n^2)\)blog
#include<bits/stdc++.h> #define rg register #define il inline #define co const template<class T>il T read(){ rg T data=0,w=1; rg char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') w=-1; ch=getchar(); } while(isdigit(ch)) data=data*10+ch-'0',ch=getchar(); return data*w; } template<class T>il T read(rg T&x){ return x=read<T>(); } typedef long long ll; co ll size=5e3+1; ll n,ans,tot,mx,d[size],tmp[size],s1[size],s2[size]; ll head[size],ver[size*2],next[size*2]; void add(ll x,ll y){ ver[++tot]=y,next[tot]=head[x],head[x]=tot; } void dfs(ll x,ll fa){ mx=std::max(mx,d[x]); tmp[d[x]]++; for(ll i=head[x];i;i=next[i]){ ll y=ver[i]; if(y==fa) continue; d[y]=d[x]+1,dfs(y,x); } } int main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); read(n); for(ll i=1;i<n;++i){ ll x=read<ll>(),y=read<ll>(); add(x,y),add(y,x); } for(ll x=1;x<=n;++x){ memset(s1,0,sizeof s1); memset(s2,0,sizeof s2); for(ll i=head[x];i;i=next[i]){ ll y=ver[i]; mx=0,d[y]=1,dfs(y,x); for(ll j=1;j<=mx;++j){ ans+=s2[j]*tmp[j]; s2[j]+=s1[j]*tmp[j]; s1[j]+=tmp[j]; } for(ll j=1;j<=mx;++j) tmp[j]=0; } } printf("%lld\n",ans); return 0; }