IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    BZOJ3522: [Poi2014]Hotel

    wyfcyx发表于 2015-08-18 20:01:14
    love 0

    题解:

    考虑三个点在树上的形态:

    (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;
    }


沪ICP备19023445号-2号
友情链接