有根树的表达

题目:Rooted Trees Aizu - ALDS1_7_A 

A graph G = (VE) is a data structure where V is a finite set of vertices and E is a binary relation on V represented by a set of edges. Fig. 1 illustrates an example of a graph (or graphs).

Fig. 1

A free tree is a connnected, acyclic, undirected graph. A rooted tree is a free tree in which one of the vertices is distinguished from the others. A vertex of a rooted tree is called "node."

Your task is to write a program which reports the following information for each node u of a given rooted tree T:

  • node ID of u
  • parent of u
  • depth of u
  • node type (root, internal node or leaf)
  • a list of chidlren of u

If the last edge on the path from the root r of a tree T to a node x is (px), then p is the parent of x, and x is a child of p. The root is the only node in T with no parent.

A node with no children is an external node or leaf. A nonleaf node is an internal node

The number of children of a node x in a rooted tree T is called the degree of x.

The length of the path from the root r to a node x is the depth of x in T.

Here, the given tree consists of n nodes and evey node has a unique ID from 0 to n-1.

Fig. 2 shows an example of rooted trees where ID of each node is indicated by a number in a circle (node). The example corresponds to the first sample input.

Fig. 2

Input

The first line of the input includes an integer n, the number of nodes of the tree.

In the next n lines, the information of each node u is given in the following format:

id k c1 c2 ... ck

where id is the node ID of uk is the degree of uc1 ... ck are node IDs of 1st, ... kth child of u. If the node does not have a child, the k is 0.

Output

Print the information of each node in the following format ordered by IDs:

node id: parent = p , depth = dtype, [c1...ck]

p is ID of its parent. If the node does not have a parent, print -1.

d is depth of the node.

type is a type of nodes represented by a string (root, internal node or leaf). If the root can be considered as a leaf or an internal node, print root.

c1...ck is the list of children as a ordered tree.

Please follow the format presented in a sample output below.

Constraints

  • 1 ≤ n ≤ 100000

Sample Input 1

13

0 3 1 4 10

1 2 2 3

2 0

3 0

4 3 5 6 7

5 0

6 0

7 2 8 9

8 0

9 0

10 2 11 12

11 0

12 0

Sample Output 1

node 0: parent = -1, depth = 0, root, [1, 4, 10]

node 1: parent = 0, depth = 1, internal node, [2, 3]

node 2: parent = 1, depth = 2, leaf, []

node 3: parent = 1, depth = 2, leaf, []

node 4: parent = 0, depth = 1, internal node, [5, 6, 7]

node 5: parent = 4, depth = 2, leaf, []

node 6: parent = 4, depth = 2, leaf, []

node 7: parent = 4, depth = 2, internal node, [8, 9]

node 8: parent = 7, depth = 3, leaf, []

node 9: parent = 7, depth = 3, leaf, []

node 10: parent = 0, depth = 1, internal node, [11, 12]

node 11: parent = 10, depth = 2, leaf, []

node 12: parent = 10, depth = 2, leaf, []

Sample Input 2

4

1 3 3 2 0

0 0

3 0

2 0

Sample Output 2

node 0: parent = 1, depth = 1, leaf, []

node 1: parent = -1, depth = 0, root, [3, 2, 0]

node 2: parent = 1, depth = 1, leaf, []

node 3: parent = 1, depth = 1, leaf, []

Note

You can use a left-child, right-sibling representation to implement a tree which has the following data:

  • the parent of u
  • the leftmost child of u
  • the immediate right sibling of u

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

思路:

在写这个代码的时候,我其实是想用一个struct直接将这个树中的节点的信息全部包起来的(父节点,子节点,深度,节点类型)。但是,在敲的过程中发现,这是不可能的。或者说这会导致大量的空间的浪费,或许可以用vector试试,但是暂时没什么时间,就不去试试了。在看了挑战程序设计书上的思路之后,才发现原来这个树是可以用左子右兄弟表示法来表示。这样子,不仅可以非常便捷地将树表示出来,满足题目要求的输出也不会占用太长的代码,真是一个好的常规有根树的表示方法。

关于树的深度的判断,我是采用了递归的方法。首先,一定要找到这个树的根节点是哪一个节点,然后,在进入递归函数findde(int po,int h)。函数中的h一定是当前节点po的的深度,记录在de数组中。之后通过节点的右指针指向该节点的相邻的右兄弟的定义递归遍历树的这一层,最后递归遍历节点的子节点,深度加1。

 void findde(int po,int h)
{
de[po]=h;
int ri=point[po].right;
int le=point[po].left;
if(ri!=-)
findde(ri,h);
if(le!=-)
findde(le,h+);
}

关于输出的话,其实就是注重一些格式的问题。不过有一点我想提一下,其实也是在敲代码的时候就出现的一点点问题。我一开始的时候用的是while循环来遍历这个节点的孩子。但是,会出现一些的格式问题,例如多了一点“, ”之类的,后来是用了两次判断l是否为-1来解决的问题,虽然是AC了,但是在while循环中其实是判断了两次的l是否为-1。这不是我希望的简洁的代码。于是我去看了一下书上的代码。惊为天人,原来还可以这样!他利用了for循环的特点完美地解决了我的问题,果然大佬就是大佬啊!

 //我的子节点的遍历输出
int l=point[i].left;
while(l!=-)
{
cout<<l;
l=point[l].right;
if(l!=-)
cout<<", ";
}
cout<<"]"<<endl;
//大佬的子节点的遍历输出
for(int j=,c=point[i].left;c!=-;j++,c=point[c].right)
{
if(j) cout<<", ";
cout<<c;
}
cout<<"]"<<endl;

AC代码:

 #include <iostream>
#include <string>
#include <cstring> using namespace std; struct Node
{
int pa;
int left; //表示的是该节点的左子节点
int right; //表示的是该节点的第一个右兄弟
};
Node point[];
int de[];
int n; void findde(int po,int h)
{
de[po]=h;
int ri=point[po].right;
int le=point[po].left;
if(ri!=-)
findde(ri,h);
if(le!=-)
findde(le,h+);
} void print()
{
for(int i=; i<n; i++)
{
cout<<"node "<<i<<": parent = "<<point[i].pa<<", depth = "<<de[i]<<", ";
if(point[i].pa==-)
cout<<"root, [";
else if(point[i].left==-)
cout<<"leaf, [";
else
cout<<"internal node, [";
//我的子节点的遍历输出
// int l=point[i].left;
// while(l!=-1)
// {
// cout<<l;
// l=point[l].right;
// if(l!=-1)
// cout<<", ";
// }
// cout<<"]"<<endl;
//大佬的子节点的遍历输出
for(int j=,c=point[i].left;c!=-;j++,c=point[c].right)
{
if(j) cout<<", ";
cout<<c;
}
cout<<"]"<<endl;
}
}
void init()
{
for(int i=;i<n;i++)
{
point[i].pa=-;
point[i].left=-;
point[i].right=-;
}
}
int main()
{
cin>>n;
memset(de,,);
init();
for(int i=; i<n; i++)
{
int a,num,l;
cin>>a>>num;
if(num)
{
cin>>l;
point[a].left=l;
point[l].pa=a;
}
for(int j=; j<num; j++)
{
int x;
cin>>x;
point[l].right=x;
point[x].pa=a;
l=x;
}
}
int root=-;
for(int i=; i<n; i++)
if(point[i].pa==-)
root=i;
findde(root,);
print();
return ;
}

总结:

这一次敲的代码反映了我的一些问题,如:敲代码之前总是不先想清楚需要的空间/定义的变量,导致写着写着忽然发现自己的想法好像不能实现,之后修改思路,这非常浪费时间。在一些细节方面,总是容易忽略,这就会导致我总是WA在细节上(虽然这一次没有),但是也在输入时候设置节点的双亲节点,子节点,兄弟节点的地方卡住了好一会。也可能是我自己的逻辑思维还是不够严密吧!加油呀!

有根树的表达 Aizu - ALDS1_7_A: Rooted Trees的更多相关文章

  1. 【Aizu - ALDS1_7_A】Rooted Trees(树的表达)

    Rooted Trees Descriptions: A graph G = (V, E) is a data structure where V is a finite set of vertice ...

  2. Tree - Rooted Trees

    Rooted Trees A graph G = (V, E) is a data structure where V is a finite set of vertices and E is a b ...

  3. HDU p1294 Rooted Trees Problem 解题报告

    http://www.cnblogs.com/keam37/p/3639294.html keam所有 转载请注明出处 Problem Description Give you two definit ...

  4. 10.3 Implementing pointers and objects and 10.4 Representing rooted trees

    Algorithms 10.3 Implementing pointers and  objects  and 10.4 Representing rooted trees Allocating an ...

  5. HDU1294 Rooted Trees Problem(整数划分 组合数学 DP)

    讲解见http://www.cnblogs.com/IMGavin/p/5621370.html, 4 可重组合 dfs枚举子树的节点个数,相乘再累加  1 #include<iostream& ...

  6. HDU 1294 Rooted Trees Problem

    题目大意:求有n个节点的树有几种? 题解:http://www.cnblogs.com/keam37/p/3639294.html #include <iostream> typedef ...

  7. [LeetCode] 310. Minimum Height Trees 解题思路

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  8. [LeetCode] Minimum Height Trees 最小高度树

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  9. Minimum Height Trees

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

随机推荐

  1. dp(过河问题)

    http://codeforces.com/gym/101492/problem/E Teamwork is highly valued in the ACM ICPC. Since the begi ...

  2. spring(二):bean的生命周期

    bean的生命周期指的是bean的创建——>初始化——>销毁的过程,该过程是由spring容器进行管理的 我们可以自定义bean初始化和销毁的方法:容器在bean进行到当前生命周期时,调用 ...

  3. mySql配置在nodejs中使用

    mySql安装完成后,配置链接nodejs项目中的数据库. 1.测试是否安装成功. 2.use nodejs使用nodejs 3.设置数据源 5.exit

  4. MapReduce-WordCountDemo

    /** * @Author: dreamer Q * @Date: 2019/11/4 22:26 * @Version 1.0 * @Discription 使用MapReduce 开发 WordC ...

  5. JavaScript深入之词法作用域和动态作用域(转载)

    作用域 作用域是指程序源代码中定义变量的区域. 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. JavaScript 采用词法作用域(lexical scoping),也就是静态作 ...

  6. 【记录】elastiasearch 6.4.3 版本 SearchRequestBuilder字段排序,BoolQueryBuilder

    参考地址: 1:https://www.cnblogs.com/shoutn/p/8027960.html 2:https://www.jianshu.com/p/8402eb930ae7 3:htt ...

  7. 2018-2-13-C#-复制列表

    title author date CreateTime categories C# 复制列表 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23:3 +0 ...

  8. linux的定时任务--crontab

    cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业.由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动.关闭这个服务: /sbin/service c ...

  9. Codeforces 633F 树的直径/树形DP

    题意:有两个小孩玩游戏,每个小孩可以选择一个起始点,并且下一个选择的点必须和自己选择的上一个点相邻,问两个选的点权和的最大值是多少? 思路:首先这个问题可以转化为求树上两不相交路径的点权和的最大值,对 ...

  10. demo board boot mode

    demo扩展板 QSPI0_IO0_MIO2--A13--PS-MIO2 QSPI0_IO0_MIO3--A14--PS-MIO3 QSPI0_IO0_MIO4--B11--PS-MIO4 QSPI0 ...