zoukankan      html  css  js  c++  java
  • 【Luogu】P3565HOT-Hotels(树形DP)

      题目链接

      水了半个月之后Fd终于开始做题啦!

      然后成功的发现自己什么都不会了

      树形DP,既然是三个点两两距离相等那一定得有个中心点吧,枚举那个中心点,然后暴力DFS,根据乘法原理算。

      乘法原理就是我一个子树,距离为i的选择情况增加tot[i],两个子树的话是一个子树的选择情况乘上tot[i],三个子树(就是答案)就是两个子树的选择情况乘上tot[i];

      挺暴力的……不过貌似POI能过了

      据说有个加强版100000数据范围,要什么长链剖分……记一下以后来填坑

      

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<algorithm>
    #define maxn 5010
    using namespace std;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Edge{
        int next,to;
    }edge[maxn*2];
    int head[maxn],num;
    inline void add(int from,int to){
        edge[++num]=(Edge){head[from],to};
        head[from]=num;
    }
    
    int dis[maxn];
    int one[maxn];
    int two[maxn];
    int tot[maxn];
    
    void dfs(int x,int fa){
        tot[dis[x]]++;
        for(int i=head[x];i;i=edge[i].next){
            int to=edge[i].to;
            if(to==fa)    continue;
            dis[to]=dis[x]+1;
            dfs(to,x);
        }
        return;
    }
    
    long long ans;
    
    int main(){
        int n=read();
        for(int i=1;i<n;++i){
            int x=read(),y=read();
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;++i){
            memset(one,0,sizeof(one));
            memset(two,0,sizeof(two));
            dis[i]=0;
            for(int j=head[i];j;j=edge[j].next){
                int to=edge[j].to;
                memset(tot,0,sizeof(tot));
                dis[to]=1;
                dfs(to,i);
                for(int k=1;k<=n;++k){
                    ans+=1LL*two[k]*tot[k];
                    two[k]+=tot[k]*one[k];
                    one[k]+=tot[k];
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    集合的笼统介绍之Collection
    集合的笼统介绍之ArrayList
    final关键字+static关键字+匿名对象
    多态
    练习018:搜索插入位置
    练习017:实现strStr()
    练习016:移除元素
    练习015:删除排序数组中的重复项
    练习014:合并两个有序链表
    用JS实现链表
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8343587.html
Copyright © 2011-2022 走看看