• P3478 [POI2008]STA-Station


    题意:

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

    发现从根从某个位置移到它的⼀一个⼦子树得出 ans 只要 O(1) 的时间

    定义 f[u] 代表以 u 为根结点的深度和 

    假设 v 是 u 的儿子 ,那么 f[v] 其实就是 v 的子树的深度全部 -1 ,其他节点的深度 + 1

    所以我们可以得到 f[v] = f[u] - siz[v] + (n - siz[v]) = f[u] + n - 2 * siz[v]

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define ls nod<<1
    #define rs (nod<<1)+1
    
    const double eps = 1e-10;
    const int maxn = 1e6 + 10;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    struct edge {
        int v,nxt;
    }e[maxn << 1];
    
    int head[maxn];
    LL dep[maxn],siz[maxn];
    int cnt,n;
    LL f[maxn];
    
    
    inline void add_edge(int u,int v) {
        e[++cnt].v = v;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    
    inline void dfs(int u,int f) {
        siz[u] = 1;
        dep[u] = dep[f] + 1;
        for (int i = head[u];~i;i = e[i].nxt) {
            int v = e[i].v;
            if (v == f)
                continue;
            dfs(v,u);
            siz[u] += siz[v];
        }
    }
    
    inline void func(int x,int fa) {
        for (int i = head[x];~i;i = e[i].nxt) {
            int v = e[i].v;
            if (fa == v)
                continue;
            f[v] = f[x] + n - siz[v] - siz[v];
            func(v,x);
        }
    }
    
    int main() {
        cnt = 0;
        memset(head,-1, sizeof(head));
        cin >> n;
        for (int i = 1;i < n;i++) {
            int u,v;
            cin >> u >> v;
            add_edge(u,v);
            add_edge(v,u);
        }
        dfs(1,0);
        for (int i = 1;i <= n;i++)
            f[1] += dep[i];
        func(1,0);
        LL ans = 0,idx = 0;
        for (int i = 1;i <= n;i++) {
            if (f[i] > ans) {
                ans = f[i];
                idx = i;
            }
        }
        cout << idx << endl;
        return 0;
    }
  • 相关阅读:
    Oracle设置某张表为只读
    greenplum不能下载问题解决方法(转)
    MyBatis学习-入门
    Oracle-数据泵使用
    oracle锁表
    linux查看文件大小
    Apache日志分割
    nginx日志切割
    zookeeper 事务日志查看
    zookeeper连接 org.apache.curator.framework.imps.CuratorFrameworkImpl Background exception was not retry-able or retry gave up [main-EventThread]
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12339693.html
Copyright © 2020-2023  润新知