有根树的表达

题目: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. B+树索引结构解析

    一.二分查找法 二分查找法(binary search)也成为折半查找法.用来查找一组有序的记录组中的某一记录. 基本思想是:将记录按有序化(递增或递减)排列,在查找过程中采用跳跃式方法查找,即先以有 ...

  2. hdu3664 Permutation Counting(dp)

    hdu3664 Permutation Counting 题目传送门 题意: 在一个序列中,如果有k个数满足a[i]>i:那么这个序列的E值为k,问你 在n的全排列中,有多少个排列是恰好是E值为 ...

  3. bzoj1779 [Usaco2010 Hol]Cowwar 奶牛战争(网络流)

    1779: [Usaco2010 Hol]Cowwar 奶牛战争 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 302  Solved: 131[Sub ...

  4. Ajax爬取豆瓣电影目录(Python)

    下面的分析相当于一个框架,搞懂之后,对于类似的文字爬取,我们也可以实现.就算不能使用Ajax方法,我们也能够使用相同思想去爬取我们想要的数据. 豆瓣电影排行榜分析 网址:https://movie.d ...

  5. eclipse不小心删除文件如何恢复

    转自:https://blog.csdn.net/u012129031/article/details/78791277 1.右键点击java项目工程名,选择restort from history, ...

  6. elasticsearch 深入 —— 近似匹配

    近似匹配 使用 TF/IDF 的标准全文检索将文档或者文档中的字段作一大袋的词语处理. match 查询可以告知我们这大袋子中是否包含查询的词条,但却无法告知词语之间的关系. 思考下面这几个句子的不同 ...

  7. MySQL 授权用户 ; 存储过程的DEFINER; 命令分隔符DELIMITER

    最近项目中遇到有人使用DEFINER这样的关键字,找了半天没有怎么理解这个意思.以为是限制谁使用这个存储过程,后来测试发现并不是这样. 搜索网上发现很多说法都不正确.看到一篇博客,做了如下介绍,才有所 ...

  8. 312-金胜维 P系列2.5寸 480G SATA3 SSD固态硬盘

    金胜维 P系列2.5寸 480G SATA3 SSD固态硬盘 一.概述     P系列为KingSpec金胜维针对入门级消费群体推出的一款高性价SSD固态硬盘,采用7mm超薄金属冲压外壳,板载优质TL ...

  9. Es学习第九课, 聚合查询和复合查询

    ES除了实现前几课的基本查询,也可以实现类似关系型数据库的聚合查询,如平均值sum.最小值min.最大值max等等 我们就用上一课的数据作为参考来举例 聚合查询 sum聚合 sum是一个求累加值的聚合 ...

  10. c++ ofstream使用方法

    ofstream是从内存到硬盘,ifstream是从硬盘到内存,流缓冲即是内存空间. 插入器<<  : 向流输出数据. cout << "test!" &l ...