• 求树的每个子树的重心


    前言:

    每个子树的重心(p)的定义:删去该点p后,以x为根的子树的所有联通块的大小均不超过 siz[x] / 2

    根据这个重心的定义可以知道一棵子树的重心必定在他自己所在的重链中. 所以每次找到他的重儿子为根的子树的重心, 不符合的话就沿着重链往上走直至找到复合要求的重心.

    模版题:http://codeforces.com/problemset/problem/685/B

    #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 = 3e5 + 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];
    
    int head[maxn],mx[maxn],ans[maxn];
    int siz[maxn],fa[maxn];
    int cnt;
    
    void add_edge(int u,int v) {
        e[++cnt].v = v;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    
    void dfs(int x) {
        siz[x] = 1;
        ans[x] = x;
        int w = 0;
        for (int i = head[x];~i;i = e[i].nxt) {
            int v = e[i].v;
            dfs(v);
            siz[x] += siz[v];
            if (siz[v] > w) {
                w = siz[v];
                mx[x] = v;
            }
        }
        int p = ans[mx[x]];
        while (p && p != fa[x]) {
            if (siz[mx[p]]*2 <= siz[x] && (siz[x]-siz[p])*2 <= siz[x]) {
                ans[x] = p;
                break;
            }
            p = fa[p];
        }
    }
    
    int main() {
        cnt = 0;
        memset(head,-1, sizeof(head));
        int n,q;
        scanf("%d%d",&n,&q);
        for (int i = 2;i <= n;i++) {
            int v;
            scanf("%d",&v);
            fa[i] = v;
            add_edge(v,i);
        }
        dfs(1);
        while (q--) {
            int x;
            scanf("%d",&x);
            printf("%d
    ",ans[x]);
        }
        return 0;
    }
  • 相关阅读:
    Java变量在内存中的存储
    Java成员变量和局部变量
    Java类的定义与类的实例化
    面向对象编程思想
    Java数组深入
    Java的Arrays类 基本用法
    Intellij IDEA如何设置快速调整字体大小的快捷键
    Win10如何快速截屏
    应用层协议原理(二)
    应用层协议原理(一)
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12332705.html
Copyright © 2020-2023  润新知