• 【BZOJ-1131】Sta 树形DP


    1131: [POI2008]Sta

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1150  Solved: 378
    [Submit][Status][Discuss]

    Description

    给出一个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

    HINT

    Source

    Solution

    树形DP裸题

    考虑转移利用子树,所以统计出size,deep之类的,第二遍计算一下答案即可

    利用换根的差值转移一下,找最大即可

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 1000010
    int N;
    struct EdgeNode{int next,to;}edge[maxn<<1];
    int head[maxn],cnt;
    void add(int u,int v)
    {
        cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt;
    }
    void insert(int u,int v) {add(u,v); add(v,u);}
    long long dp[maxn]; int deep[maxn],size[maxn],fa[maxn];
    void DFS(int x)
    {
        size[x]=1;
        dp[x]=deep[x];
        for (int i=head[x]; i; i=edge[i].next)
            if (edge[i].to!=fa[x])
                {
                    deep[edge[i].to]=deep[x]+1;
                    fa[edge[i].to]=x;
                    DFS(edge[i].to);
                    dp[x]+=dp[edge[i].to];
                    size[x]+=size[edge[i].to];
                }
    }
    void DP(int x)
    {
        for (int i=head[x]; i; i=edge[i].next)
            if (edge[i].to!=fa[x])
                {
                    dp[edge[i].to]=dp[x]+N-2*size[edge[i].to];    
                    DP(edge[i].to);
                }
    }
    int main()
    {
        N=read();
        for (int u,v,i=1; i<=N-1; i++)
            u=read(),v=read(),insert(u,v);
        DFS(1); DP(1);
        long long maxx=0; int ans;
        for (int i=1; i<=N; i++)
            if (dp[i]>maxx) ans=i,maxx=dp[i];
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    三大范式
    html 横线的代码
    CSS下拉 菜单3.27第一次
    JS页面三种打开方式及对话框
    函数整理
    3.22整理作业
    for循环,if 练习
    php测试题
    设计模式
    面向对象的三大特性
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5488534.html
Copyright © 2020-2023  润新知