• 【满k叉树】Perfect Tree


    题目描述

    Given a positive integer k, we define a rooted tree to be k-perfect, if and only if it meets both conditions below:
    •Each node is either a leaf node or having exactly k direct offsprings.
    •All leaf nodes have the same distance to the root (i.e., all leaf nodes are of the same depth).
    Now you are given an unrooted tree, and you should answer these questions:
    •Is it possible to assign it a root, so that the tree becomes k-perfect for some positive integer k?
    •If possible, what is the minimal k?
     

    输入

    Read from the standard input.
    Each input contains multiple test cases.
    The first line contains a single positive integer T, indicating the number of test cases.
    For each test case, its first line contains a positive integer n, describing the number of tree nodes. Each of the next n − 1 lines contains two space-separated integers u and v, which means there exists an edge between node u and v on the tree.
    It is guaranteed each test case gives a valid unrooted tree, and the nodes are numbered with consecutive integers from 1 to n.
    The sum of n in each input will not exceed 1e6.
     

    输出

    Write to the standard output.
    For each test case, output a single integer in a line:
    •If the answer to the first question is "No", output −1.
    •Otherwise, output the minimal k.
     

    样例输入

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

    样例输出

    2
    -1



    【题意】

      给出n个点,n-1条边的无根树,请问这颗无根树是否为满k叉树,如果是满k叉树,请输出k。否则输出"-1".

    【感受】

      太多细节了,真的太多太多了,WA29次.......

      最后还是看了别人的代码才知道自己错哪里了。

      

      根据树的特点观察得到:

      度的情况有以下情况:

      度数为1 :叶子节点

           度数为k :根节点  (同时只有1个)

      度数为k+1 :其他节点。

      特例:

      1、菊花图,就是一个节点连着多个叶子节点

      2、单链

      3、满K叉树

      4、否则都不满足。


      1 #pragma GCC optimize(2)
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 const int N = 2e6+10;
      5 const int inf = 0x3f3f3f3f ;
      6 
      7 /*——————————————————Add_edge()————————————————*/
      8 
      9 typedef struct Edge{
     10     int to , next ;
     11 }Edge ;
     12 Edge e[N<<1];
     13 int head[N] , cnt ;
     14 
     15 void Add_edge( int u , int v ){
     16     e[cnt] = Edge{ v ,head[u] };
     17     head[u] = cnt ++ ;
     18 }
     19 
     20 /*——————If you ask me how much i love you ———————*/
     21 
     22 int vis[N],du[N],dep[N],Num[N],n;
     23 int p[N];
     24 void Init(){
     25     for(int i=0;i<=n;i++){
     26         head[i] = -1 ;
     27         Num[i] = dep[i] = p[i] = vis[i] = du[i] = 0 ;
     28     }
     29     cnt = 0 ;
     30 }
     31 int main()
     32 {
     33     int T;
     34     scanf("%d",&T);
     35     while(T--){
     36         
     37         scanf("%d",&n);
     38         Init();
     39 
     40         for( int i = 1,u,v ; i < n ; i++ ){
     41             scanf("%d%d",&u,&v);
     42             Add_edge( u , v );
     43             Add_edge( v , u );
     44             du[u] ++ ; du[v] ++ ;
     45         }
     46         //直接判断节点个数<=3时都为1.
     47         if( n <= 3 ){           
     48             printf("1
    ");
     49             continue ;
     50         }
     51 
     52         bool f = true;
     53 
     54         int tot = 0 ;
     55         for(int u = 1 ; u <= n ; u ++ ){
     56             if( vis[du[u]] == 0 )
     57                 p[tot++] = du[u] ;
     58             vis[du[u]] ++ ;
     59         }
     60 
     61         sort( p , p + tot );
     62         int k = p[1] ;
     63         
     64         //单链情况
     65         if( tot == 2 && vis[1] == 2 ){ 
     66             printf("1
    ");      continue ;
     67         }
     68         //具有一层的情况
     69         else if( tot == 2 && vis[1] == n - 1 ){    
     70             printf("%d
    ",p[1]) ; continue ;
     71         }
     72         // 度数为k的只有一个,而且第三种度的个数一定是K+1
     73         else if( tot == 3 ){
     74             if( vis[p[1]] != 1 || p[1] != p[2] - 1 ){   
     75                 f = false ;
     76             }else{
     77                 int root = 0 , Max_dep = 0 ;
     78                 for(int u = 1 ; u <= n ; u++ ){
     79                     if( du[u] == p[1] ){
     80                         root = u ;
     81                         break ;
     82                     }
     83                 }
     84             /*  利用深度来判断是否为满K叉树      */
     85                 queue< int > Q ;
     86                 Q.push( root );
     87 
     88                 dep[root] = 0 ;
     89                 Num[0] ++ ;
     90                 
     91                 while( !Q.empty() ){
     92                     int u = Q.front() ;
     93                     Q.pop();
     94                     du[u] = -1 ;
     95                     for(int i = head[u] ; ~i ; i = e[i].next ){
     96                         int To = e[i].to;
     97                         if( du[To] == -1 ) continue ;
     98                         dep[To] = dep[u] + 1 ;
     99                         Num[dep[To]] ++ ;
    100                         Max_dep = max( dep[To] , Max_dep );
    101                         Q.push(To);
    102 
    103                     }
    104                 }
    105 
    106                 for(int i=0;i<Max_dep;i++){
    107                     if( Num[i]*k != Num[i+1] ) f = false ;
    108                 }
    109             }
    110         }else{
    111             f = false ;
    112         }
    113         
    114         if( f ){
    115             printf("%d
    ",k);
    116         }else{
    117             printf("-1
    ");
    118         }
    119     }
    120     return 0 ;
    121 }
    122 
    123 /*
    124 10
    125 7
    126 1 4
    127 4 5
    128 3 1
    129 2 3
    130 7 3
    131 4 6
    132 7
    133 1 4
    134 1 5
    135 1 2
    136 5 3
    137 5 6
    138 5 7
    139 13
    140 1 2
    141 1 3
    142 1 4
    143 2 5
    144 2 6
    145 2 7
    146 3 8
    147 3 9
    148 3 10
    149 5 11
    150 5 12
    151 5 13
    152 5
    153 1 2
    154 2 3
    155 3 4
    156 4 5
    157 
    158 */
    View Code
  • 相关阅读:
    【洛谷3778】[APIO2017] 商旅(分数规划+Floyd)
    【AT4114】[ARC095D] Permutation Tree(简单题)
    【AT4352】[ARC101C] Ribbons on Tree(容斥+DP)
    【AT4169】[ARC100D] Colorful Sequences(DP)
    【洛谷4581】[BJOI2014] 想法(随机算法)
    【洛谷5659】[CSP-S2019] 树上的数(思维)
    【AT4439】[AGC028E] High Elements(线段树)
    【CF590E】Birthday(AC自动机+二分图匹配)
    【洛谷4298】[CTSC2008] 祭祀(Dilworth定理+二分图匹配)
    【洛谷3774】[CTSC2017] 最长上升子序列(杨表)
  • 原文地址:https://www.cnblogs.com/Osea/p/11441420.html
Copyright © 2020-2023  润新知