码迷,mamicode.com
首页 > 其他好文 > 详细

求树的每个子树的重心

时间:2020-02-19 20:42:25      阅读:81      评论:0      收藏:0      [点我收藏+]

标签:class   algorithm   time   ORC   pre   根据   --   memset   void   

前言:

每个子树的重心(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\n",ans[x]);
    }
    return 0;
}

 

求树的每个子树的重心

标签:class   algorithm   time   ORC   pre   根据   --   memset   void   

原文地址:https://www.cnblogs.com/-Ackerman/p/12332705.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!