• cf 686D


    题目:传送门

    思路:显然 ,以 u 为根节点的子树的重心(设为ans[u] ),一定是在 ans[v] 到 u 的路径上,其中 v 是 u 的重儿子。

       最暴力的思路,便是枚举路径上的所有点,但这样会出现大量的重复枚举,例如当树退化成线性结构,这种做法的复杂度也会退化成O(n2)。所以,这个时候可以利用重心的一个性质:以重心为根,所有子树的重量均<=原树重量/2 (重子树的重量<=原树重量/2)

      那么,复杂度就可以优化到O(n) ,因为对于每个点重儿子只有一个,且枚举不重复。

    代码:

     1 //#include<bits/stdc++.h>
     2 
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<vector>
     7 #include<cctype>
     8 #include<queue>
     9 #include<algorithm>
    10 #include<map>
    11 #include<set>
    12 
    13 #pragma GCC optimize(2)
    14 using namespace std;
    15 typedef long long LL;
    16 typedef pair<int,int> pii;
    17 typedef pair<double,double> pdd;
    18 const int N=1e6+5;
    19 const int M=1e4+5;
    20 const int inf=0x3f3f3f3f;
    21 const LL mod=1e9+7;
    22 const double eps=1e-9;
    23 const long double pi=acos(-1.0L);
    24 #define ls (i<<1)
    25 #define rs (i<<1|1)
    26 #define fi first
    27 #define se second
    28 #define pb push_back
    29 #define mk make_pair
    30 #define mem(a,b) memset(a,b,sizeof(a))
    31 LL read()
    32 {
    33     LL x=0,t=1;
    34     char ch;
    35     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    36     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    37     return x*t;
    38 }
    39 vector<int> e[N];
    40 int son[N],cnt[N],f[N],ans[N];
    41 void dfs(int u,int pre)
    42 {
    43     cnt[u]=1;
    44     f[u]=pre;
    45     for(auto v:e[u])
    46     {
    47         if(v==pre) continue;
    48         dfs(v,u);
    49         cnt[u]+=cnt[v];
    50         if(cnt[son[u]]<cnt[v]) son[u]=v;
    51     }
    52     ans[u]=u;
    53     if(son[u])
    54     {
    55         int p=ans[son[u]];
    56         while(p!=u&&(cnt[u]-cnt[p])*2>cnt[u]) p=f[p];
    57         ans[u]=p;
    58     }
    59 }
    60 int main()
    61 {
    62     int n=read(),m=read();
    63     for(int i=2;i<=n;i++)
    64     {
    65         int x=read();
    66         e[x].pb(i);
    67         e[i].pb(x);
    68     }
    69     dfs(1,0);
    70     for(int i=1;i<=m;i++)
    71     {
    72         int x=read();
    73         printf("%d
    ",ans[x]);
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    使用图形化界面打包自己的类库
    搭建自己的NuGet服务器,上传自定义NuGet包
    在内部架设NuGet服务器
    Prism简介
    Nhibernate Icreteria 分页查询
    uDig介绍
    基于Geoserver配置多图层地图以及利用uDig来进行样式配置
    如何在GeoServer上发布一张地图
    XML的SelectNodes使用方法以及XPath
    coded ui run in interactive mode
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12937553.html
Copyright © 2020-2023  润新知