• poj 1655 Balancing Act 树的重心


    题目链接:http://poj.org/problem?id=1655

    Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created by deleting that node from T. 
    For example, consider the tree:

     

    Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two. 

    For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.

    题意描述:略。找出重心以及删除重心后两颗子树中结点数大的一颗。

    算法分析:重在分析重心问题,一颗树的重心就是所有节点的子节点的数量最大的最小的节点。简而言之,重心就是要让这棵树在节点个数上达到左右子树相对平衡的这样一个节点。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #define inf 0x7fffffff
    10 using namespace std;
    11 const int maxn=20000+10;
    12 const int M = 20000+10;
    13 
    14 int n;
    15 struct node
    16 {
    17     int v,next;
    18 }edge[M*3];
    19 int head[maxn],edgenum;
    20 
    21 void add(int u,int v)
    22 {
    23     edge[edgenum].v=v ;edge[edgenum].next=head[u] ;head[u]=edgenum++ ;
    24     edge[edgenum].v=u ;edge[edgenum].next=head[v] ;head[v]=edgenum++ ;
    25 }
    26 
    27 int an[maxn],bn[maxn];
    28 int dfs(int u,int pre)
    29 {
    30     an[u]=bn[u]=1;
    31     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
    32     {
    33         int v=edge[i].v;
    34         if (v != pre)
    35         {
    36             int k=dfs(v,u);
    37             an[u] += k;
    38             bn[u]=max(bn[u],k);
    39         }
    40     }
    41     return an[u];
    42 }
    43 
    44 int main()
    45 {
    46     int t;
    47     scanf("%d",&t);
    48     while (t--)
    49     {
    50         scanf("%d",&n);
    51         memset(head,-1,sizeof(head));
    52         edgenum=0;
    53         int a,b;
    54         for (int i=1 ;i<n ;i++)
    55         {
    56             scanf("%d%d",&a,&b);
    57             add(a,b);
    58         }
    59         int k=dfs(1,1);
    60         int ans=inf,num=n;
    61         for (int i=1 ;i<=n ;i++)
    62         {
    63             bn[i]=max(bn[i],n-an[i]);
    64             if (ans>bn[i] || (ans==bn[i] && n>i))
    65             {
    66                 ans=bn[i];
    67                 num=i;
    68             }
    69         }
    70         printf("%d %d
    ",num,ans);
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    利用XShell上传、下载文件(使用sz与rz命令)
    我做的一个websocket的demo(php server)
    linux下如何实现mysql数据库每天自动备份定时备份
    php利用ob缓存机制实现页面静态化方法全解
    MySQL数据备份之mysqldump使用
    将jpg压缩成webp格式的图片
    ab网站压力测试命令的参数、输出结果的中文注解
    网页优化实例
    JQ 为未来元素添加事件处理器—事件委托
    Web前端优化最佳实践及工具集锦
  • 原文地址:https://www.cnblogs.com/huangxf/p/4367436.html
Copyright © 2020-2023  润新知