• STA树的深度(树型DP)


    STA树的深度

    题目大意

    给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大

    Input

    给出一个数字N,代表有N个点.N<=1000000 下面N-1条边.

    Output

    输出你所找到的点,如果具有多个解,请输出编号最小的那个.

    Sample Input

    8
    1 4
    5 6
    4 5
    6 7
    6 8
    2 4
    3 4

    Sample Output

    7

    Solution

    两种思路
    第一就是贪心爆搜
    第二就是DP
    显然这道题贪心不可做
    那么来考虑动态规划
    设根节点为i的答案是(dp_i)
    当前节点u的规模为(size_u)
    那么更新答案的时候每次向下寻找一个子节点
    深度就(-=size_v)并且(+=(n - size_v))
    现在只需要预处理出第一个(dp_1)
    即可对所有状态进行转移

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    
    inline int read(){
        int x = 0, w = 1;
        char ch = getchar();
        for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
        return x * w;
    }
    
    const int maxn = 55505;
    struct node{
        int to, nxt, w;
    }edge[maxn << 1];
    
    int n;
    int head[maxn], tot;
    int ans[maxn];
    
    inline void add(int x, int y){
        edge[++tot].to = y;
        edge[tot].nxt = head[x];
        // edge[tot].w = z;
        head[x] = tot;
    }
    
    int siz[maxn];
    int dp[maxn];
    int dep[maxn];
    inline void dfs(int u,int fa){
        siz[u]=1;
        dp[u]=dep[u];
        for(int i=head[u];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(v==fa)continue;
            dep[v]=dep[u]+1;
            dfs(v,u);
            siz[u]+=siz[v];
            dp[u]+=dp[v];
        }
    }   
    
    inline void calc(int u,int fa){
        for(int i=head[u];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(v==fa)continue;
            dp[v]=dp[u]-siz[v]+n-siz[v];
            calc(v,u);
        }
    }
    signed main(){
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int a = read(), b = read();
            add(a,b);
            add(b,a);
        }
        dfs(1,0);
        calc(1,0);
        int ans=0;
        for(int i=1;i<=n;i++)
            if(dp[ans]<dp[i])ans=i;
        printf("%d
    ",ans);
    }
    
  • 相关阅读:
    TypeScript
    Jmeter注册100个账户的三个方法
    Jmeter之cookie处理的2中方法
    Jmeter_JsonPath 提取器
    Jmeter_正则表达式提取器_提取数组 & For Each 控制器
    Jmeter_正则表达式提取器_提取单组数据
    Jmeter_选项_函数助手_RandomString的用法
    Jmeter_正则表达式
    Jmeter_选项_函数助手对话框_CSVRead
    Jmeter_请求原件之参数化CSV
  • 原文地址:https://www.cnblogs.com/rui-4825/p/12692897.html
Copyright © 2020-2023  润新知