zoukankan      html  css  js  c++  java
  • BZOJ 1131: [POI2008]Sta( dfs )

     对于一棵树, 考虑root的答案向它的孩子转移, 应该是 ans[son] = (ans[root] - size[son]) + (n - size[son]).

    so , 先 dfs 预处理一下, 然后再 DFS 求出各点答案 , 取最优即可 

    -----------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
     
    #define rep(i ,n) for(int i=0; i < n; ++i)
    #define clr(x ,c) memset(x, c, sizeof(x))
     
    using namespace std;
     
    typedef long long ll;
     
    const int maxn = 1000005;
     
    struct edge {
    int to;
    edge*next;
    } E[maxn << 1], *pt = E, *head[maxn];
     
    void add(int u, int v) {
    pt->to = v;
    pt->next = head[u];
    head[u] = pt++;
    }
    #define add_edge(u, v) add(u, v), add(v, u)
     
    int size[maxn], dep[maxn], n;
    ll ans[maxn];
     
    void init() {
    clr(head, 0);
    cin >> n;
    rep(i, n - 1) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--, v--;
    add_edge(u, v);
    }
    }
     
    void dfs(int x, int fa) {
    size[x] = 1;
    for(edge*e= head[x]; e; e = e->next) if(e->to != fa) {
    ans[0] += (dep[e->to] = dep[x] + 1);
    dfs(e->to, x);
    size[x] += size[e->to];
    }
    }
     
    void DFS(int x, int fa) {
    for(edge*e = head[x]; e; e = e->next) if(e->to != fa) {
    ans[e->to] = ans[x] + n - 2 * size[e->to];
    DFS(e->to, x);
    }
    }
     
    void work() {
    ans[0] = dep[0] = 0;
    dfs(0, -1);
    DFS(0, -1);
    cout << max_element(ans, ans + n) - ans + 1 << " ";
    }
     
    int main(){
    freopen( "test.in" , "r" , stdin );
    init();
    work();
    return 0;

    -----------------------------------------------------------------------------------------------

    1131: [POI2008]Sta

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 870  Solved: 271
    [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

  • 相关阅读:
    求解大于或等于某个4字节正整数的最小2次幂
    C++17 std::optional
    C++主动调用析构函数
    std::raise()
    C++ std::integral_constant
    C++ range-v3库的安装与测试[Utunbu 18.04]
    python将YUV420P文件转PNG图片格式
    python将两张图片横向或者纵向合成一张
    folly库之Benchmark.h
    Facebook的folly库在Utunbu上的编译
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4655316.html
Copyright © 2011-2022 走看看