zoukankan      html  css  js  c++  java
  • POJ 1655.Balancing Act-树的重心(DFS) 模板(vector存图)

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 17497   Accepted: 7398

    Description

    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. 

    Input

    The first line of input contains a single integer t (1 <= t <= 20), the number of test cases. The first line of each test case contains an integer N (1 <= N <= 20,000), the number of congruence. The next N-1 lines each contains two space-separated node numbers that are the endpoints of an edge in the tree. No edge will be listed twice, and all edges will be listed.

    Output

    For each test case, print a line containing two integers, the number of the node with minimum balance and the balance of that node.

    Sample Input

    1
    7
    2 6
    1 2
    1 4
    4 5
    3 7
    3 1
    

    Sample Output

    1 2

    Source

     
     
     
     
    题意就是找树的重心,然后通过树的重心的概念,找到树的重心,删掉之后子树是最平衡的。直接贴的模板。
     
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<bitset>
     6 #include<cassert>
     7 #include<cctype>
     8 #include<cmath>
     9 #include<cstdlib>
    10 #include<ctime>
    11 #include<deque>
    12 #include<iomanip>
    13 #include<list>
    14 #include<map>
    15 #include<queue>
    16 #include<set>
    17 #include<stack>
    18 #include<vector>
    19 using namespace std;
    20 typedef long long ll;
    21 typedef long double ld;
    22 typedef pair<int,int> pii;
    23 
    24 const double PI=acos(-1.0);
    25 const double eps=1e-6;
    26 const ll mod=1e9+7;
    27 const int inf=0x3f3f3f3f;
    28 const int maxn=1e5+10;
    29 const int maxm=100+10;
    30 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    31 
    32 int n,father;
    33 int siz[maxn];//siz保存每个节点的子树大小
    34 bool vist[maxn];
    35 int point=inf,minsum=-1;//minsum表示切掉重心后最大连通块的大小
    36 vector<int>G[maxn];
    37 
    38 void DFS(int u,int x)//遍历到节点x,x的父亲是u
    39 {
    40     siz[x]=1;
    41     bool flag=true;
    42     for(int i=0;i<G[x].size();i++){
    43         int v=G[x][i];
    44         if(!vist[v]){
    45             vist[v]=true;
    46             DFS(x,v);//访问子节点。
    47             siz[x]+=siz[v];//回溯计算本节点的siz
    48             if(siz[v]>n/2) flag=false;//判断节点x是不是重心。
    49         }
    50     }
    51     if(n-siz[x]>n/2) flag=false;//判断节点x是不是重心。
    52     if(flag&&x<point) point=x,father=u;//这里写x<point是因为本题中要求节点编号最小的重心。
    53 }
    54 
    55 void init()
    56 {
    57     memset(vist,false,sizeof(vist));
    58     memset(siz,0,sizeof(siz));
    59     minsum=-1;
    60     point=inf;
    61     for(int i=0;i<maxn;i++) G[i].clear();
    62 }
    63 
    64 int main()
    65 {
    66     int t;
    67     scanf("%d",&t);
    68     while(t--){
    69         scanf("%d",&n);
    70         init();
    71         for(int i=1;i<n;i++){
    72             int u,v;
    73             scanf("%d%d",&u,&v);
    74             G[u].push_back(v);
    75             G[v].push_back(u);
    76         }
    77         vist[1]=1;
    78         DFS(-1,1);//任意选取节点作为根,根节点的父亲是-1。
    79         for(int i=0;i<G[point].size();i++)
    80             if(G[point][i]==father) minsum=max(minsum,n-siz[point]);
    81             else minsum=max(minsum,siz[G[point][i]]);
    82         printf("%d %d
    ",point,minsum);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    utils:一个通用枚举类
    代码片段(二):SQL片段
    Scala:(一) 特点及安装环境配置
    Scala:(二) 语言基础-数据结构、表达式(判断、循环、块表达式)
    11-docker搭建mysql一主一从
    10-docker搭建rabbitmq集群
    尚硅谷周阳面试第二季
    docker 修改mysql 表大小写铭感
    volatile的理解
    消息队列优缺点及其选型
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10305516.html
Copyright © 2011-2022 走看看