家谱
描述
家谱:又称族谱、宗谱等。是一种以表谱形式,记载一个家族的世系繁衍及重要人物事迹的书。皇帝的家谱称玉牒,如新朝玉牒、皇宋玉牒。它以记载父系家族世系、人物为中心,由正史中的帝王本纪及王侯列传、年表等演变而来。
家谱是一种特殊的文献,就其内容而言,是中国五千年文明史中具有平民特色的文献,记载的是同宗共祖血缘集团世系人物和事迹等方面情况的历史图籍。家谱属珍贵的人文资料,对于历史学、民俗学、人口学、社会学和经济学的深入研究,均有其不可替代的独特功能。
这一天小白拿到了自己家的家谱,小白便想知道自己家的家谱中,每位祖先有多少孩子(他孩子的孩子也是他的孩子)。但是家族历史源远流长,家谱实在太庞大了,自己一个人完全数不过来。热心的你便自告奋勇帮小白写一个程序,来统计每位祖先他有多少孩子。
输入
输入的第一行有一个整数 n(1 ≤ n ≤ 100000),表示家谱中总共的人数。
然后有 n-1行,每行有两个整数 x(1 ≤ x ≤ n), y(1 ≤ y ≤ n)表示 x 是 y 的父亲。
输出
输出 n 行,每行有一个整数,表示第 i 个人他有多少孩子。
输入样例 1
4
1 2
1 3
2 4
输出样例 1
3
1
0
0
手续:
使用DFS来将整个节点处理。
将起子节点的数量给存到数组里,处理。
没有父节点的就是祖先根节点。
代码手续:
1.用动态数组来储存起值:
vector<int> a[100010];//动态数组的定义
int father[100010];
int sons[100010];
2.算儿子的数量:(核心)
void dfs(int u){
for (int i=0;i<a[u].size();i++){
int v=a[u][i];
dfs(v);
sons[u]+=sons[v]+1;//算儿子的数量,放到sons数组里面
}
}
3.动态数组输入:
for (int i=1;i<n;i++){
int x,y;
cin >> x>>y;
father[y] = x;
a[x].push_back(y);
}
到了这里就复杂起来了,你要搞清楚哪个点对应什么,父节点如何分配。
4.处理节点:
int u;
for (int i=1;i<n;i++){
if (father[i]==0){
u=i;//没有父节点的就是祖先根节点
}
}
dfs(u);
程序到了这里,基本上就结束了,另外的就需要输出儿子的你那一份。
代码:
#include <bits/stdc++.h>
using namespace std;
vector<int> a[100010];//动态数组的定义
int father[100010];
int sons[100010];
void dfs(int u){
for (int i=0;i<a[u].size();i++){
int v=a[u][i];
dfs(v);
sons[u]+=sons[v]+1;//算儿子的数量,放到sons数组里面
}
}
int main(){
int n;
cin >> n;
for (int i=1;i<n;i++){
int x,y;
cin >> x>>y;
father[y] = x;
a[x].push_back(y);
}
int u;
for (int i=1;i<n;i++){
if (father[i]==0){
u=i;//没有父节点的就是祖先根节点
}
}
dfs(u);
for (int i=1;i<=n;i++){
cout << sons[i]<<endl;//输出
}
return 0;
}
这篇博客介绍了家谱的概念及其在历史、文化中的重要性。作者帮助小白编写了一个程序,通过深度优先搜索(DFS)来统计家谱中每个人的父亲和孩子数量。文章提供了输入输出示例,并详细解释了代码实现的四个关键步骤:动态数组初始化、计算子节点数量、动态数组输入和处理节点。
9991

被折叠的 条评论
为什么被折叠?



