1. 问题背景与需求分析
在企业管理系统中,我们经常需要统计组织架构中每个管理者的直接和间接下属数量。这道题目将这一实际业务需求抽象为一个经典的树形结构问题:给定公司的层级关系,计算每位员工的下属总人数(包含直接下属和间接下属)。
1.1 问题形式化描述
输入:
- 第一行:整数n(1≤n≤2×10^5),表示员工总数
- 后续n-1行:第i个数字表示员工i+1的直接上司编号(员工1为总经理,没有上司)
输出:
- n个整数,第i个数字表示员工i的下属总人数
示例:
输入:
5
1 1 2 3
输出:
4 1 1 0 0
1.2 数据结构选择考量
面对2×10^5的数据规模,我们需要特别关注算法的时间复杂度和空间复杂度:
- 邻接矩阵:空间复杂度O(n^2),对于n=2×10^5需要约160GB内存,显然不可行
- 标准邻接表:使用vector<vector
>存储,虽然空间复杂度O(n),但存在动态扩容开销 - 链式前向星:用数组模拟链表,空间利用率最高,访问效率稳定,是本题最优选择
提示:在算法竞赛中,当n≥10^5时,链式前向星通常是处理稀疏图的首选数据结构
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法设计与实现
2.1 树形DFS算法原理
这个问题本质上是计算树中每个节点的子树大小(包含自身),然后减1得到下属人数。我们采用后序遍历的DFS策略:
- 从根节点(总经理)开始递归
- 对于每个节点,先递归处理所有子节点
- 将子节点的子树大小累加到当前节点
- 当前节点的子树大小即为所有子节点子树大小之和加1(自身)
2.2 链式前向星实现细节
链式前向星是一种用数组模拟邻接表的高效存图方式,包含三个核心数组:
cpp复制int h[N]; // h[u]:节点u的第一条边的索引
int vtex[M]; // 边的终点
int nxt[M]; // 下一条兄弟边的索引
int idx = 0; // 当前可用的边索引
void addedge(int u, int v) {
vtex[idx] = v;
nxt[idx] = h[u];
h[u] = idx++;
}
初始化时需要特别注意:
cpp复制memse
