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;
}
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息