zoukankan      html  css  js  c++  java
  • CF 686D. Kay and Snowflake

    给你一个树N个点,再给出Q个询问,问以x为根的子树中,重心是哪个?
    2≤n≤300000,1≤q≤30000

    Sol:
    从下到上,根据性质做一下.
    1:如果某个点x,其子树y的大小超过总结点个数一半,则重心在y这个子树中。
    2:如果某个树的重心点,其上方点的个数多于其下方点的,则重心要上移

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 300000+10;
    int n,q;
    vector<int> G[N]; ///存图
    int ans[N];       ///答案
    int son[N];       ///包括自身在内有多少子树结点
    int fa[N];        ///输入用,同时代表这个点的父亲
     
    void dfs(int u){
        ans[u] = u;//当只有一个点时,重心为其自己 
        son[u] = 1;
        for(int i = 0;i < G[u].size();i++){
            int v = G[u][i];
            dfs(v);
            son[u] += son[v];
        }
        for(int i = 0;i < G[u].size();i++)     
            if(son[G[u][i]]*2 > son[u])
    		//如果有一个子树超过总个数一半,则重心在这个子树中        
    		    ans[u] = ans[G[u][i]];
        while((son[u]-son[ans[u]])*2 > son[u]) 
        //如果当前重心上方的点,比它下方的点要多,则重心要进行移动 
            ans[u] = fa[ans[u]];
    }
     
    int main(void)
    {
        scanf("%d%d",&n,&q);
        for(int i = 2;i <= n;i++){
            scanf("%d",&fa[i]);
            G[fa[i]].push_back(i);
        }
        dfs(1);
        for(int i = 1;i <= q;i++){
            int qq;
            scanf("%d",&qq);
            printf("%d
    ",ans[qq]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    leetcode 141. Linked List Cycle
    leetcode 367. Valid Perfect Square
    leetcode150 Evaluate Reverse Polish Notation
    小a与星际探索
    D. Diverse Garland
    C. Nice Garland
    数的划分(动态规划)
    平衡二叉树(笔记)
    1346:【例4-7】亲戚(relation)
    1192:放苹果(dp + 搜索)
  • 原文地址:https://www.cnblogs.com/cutemush/p/11830897.html
Copyright © 2011-2022 走看看