LG3565 [POI2014]HOT-Hotels

题意

有一个树形结构,每条边的长度相同,任意两个节点能够相互到达。选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;
}
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息