zoukankan      html  css  js  c++  java
  • POJ 1655 Balancing Act (树的重心,常规)

    题意:求树的重心,若有多个重心,则输出编号较小者,及其子树中节点最多的数量。

    思路:

      树的重心:指的是一个点v,在删除点v后,其子树的节点数分别为:u1,u2....,设max(u)为其中的最大值,点v的max(u)是所有点里面最小的,称v为树的重心。

      如何求任一重心?按树形来看,max(v)可以由其父亲贡献,也可以由其任一孩子贡献。孩子比较好解决,不就是深搜一遍,然后回溯时统计下数量就行了?而父亲的怎么办?可以知道,点v到其父亲这一叉就是n-sum(v)了,sum(v)指的是以v为根的子树的节点数。那么一次DFS就可以知道答案了,复杂度O(n)。

     1 //#include <bits/stdc++.h>
     2 #include <vector>
     3 #include <iostream>
     4 #include <cstdio>
     5 #include <cstring>
     6 #define pii pair<int,int>
     7 #define INF 0x3f3f3f3f
     8 #define LL long long
     9 using namespace std;
    10 const int N=20100;
    11 int n, vis[N], cnt[N];
    12 vector<int> vect[N];
    13 int DFS(int x)      //深搜求删除任一点后,其某一子树的节点数量达到的最大值。
    14 {
    15     vis[x]=1;
    16     int big=0,sum=0;
    17     for(int i=0; i<vect[x].size(); i++)
    18     {
    19         if(!vis[vect[x][i]])
    20         {
    21             int t=DFS(vect[x][i]);
    22             big=max(t,big);
    23             sum+=t;
    24         }
    25     }
    26     cnt[x]=max(big, n-sum-1);
    27     return sum+1;
    28 }
    29 
    30 int main()
    31 {
    32     //freopen("input.txt", "r", stdin);
    33     int t,a,b;cin>>t;
    34     while(t--)
    35     {
    36         scanf("%d",&n);
    37         memset(vis,0,sizeof(vis));
    38         memset(cnt,0,sizeof(cnt));
    39         for(int i=0; i<=n; i++) vect[i].clear();
    40         for(int i=1; i<n; i++)
    41         {
    42             scanf("%d%d",&a,&b);
    43             vect[a].push_back(b);
    44             vect[b].push_back(a);
    45         }
    46         DFS(1);
    47         int big=INF, pos;
    48         for(int i=1; i<=n; i++)
    49         {
    50             if(cnt[i]<big)
    51             {
    52                 big=cnt[i];
    53                 pos=i;
    54             }
    55         }
    56         printf("%d %d
    ", pos, big);
    57     }
    58     return 0;
    59 }
    AC代码
  • 相关阅读:
    [转]面向接口编程详解(二)——编程实例
    [转]面向接口编程详解(一)——思想基础
    [转] LINQ to SQL快速上手 step by step
    Java备份MySQl数据库,并备份图片数据
    用密码密码拦截
    引用 MySQL集群:主从数据库配置 实现查询负载
    Oracle 对表操作 提示:资源正忙,要求指定nowait
    Jquery一款非好的图片轮换效果
    CodeBlocks集成ObjectiveC开发 Windows下学习ObjectiveC
    查询指定库中所有表
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4808212.html
Copyright © 2011-2022 走看看