小 A 有一棵 n 个结点的树,这些结点依次以 1, 2, ⋯, n 标号。
小 A 想在这棵树上漫步。具体来说,小 A 会从树上的某个结点出发,每⼀步可以移动到与当前结点相邻的结点,并且小 A 只会在偶数步(可以是零步)后结束漫步。
现在小 A 想知道,对于树上的每个结点,从这个结点出发开始漫步,经过偶数步能结束漫步的结点有多少个(可以经过重复的节点)。
【输入描述】
第一行,一个正整数 n。
接下来 n−1 行,每行两个整数 ui ,vi ,表示树上有⼀条连接结点 ui 和结点 vi 的边。
【输出描述】
一行,n 个整数。第 i 个整数表示从结点 i 出发开始漫步,能结束漫步的结点数量。
【数据范围】
保证 1 ≤ n ≤ 2×105
【输入样例】
4
1 3
3 2
4 3
【输出样例】
3 3 1 3
【题解图】

【参考程序】
// 爱码岛编程
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
vector<int> adj[MAXN]; // 邻接表
int depth[MAXN]; // 记录每个结点的深度
int evenCnt = 0; // 深度是偶数的结点数量
int oddCnt = 0; // 深度奇数的结点数量
// 深度优先遍历
void dfs(int u, int parent, int d) {
depth[u] = d; // 记录当前结点的深度
if (d % 2 == 0) {
evenCnt++;
} else {
oddCnt++;
}
for (int i = 0; i < adj[u].size(); i++) {
int v = adj[u][i];
if (v != parent) {
dfs(v, u, d + 1);
}
}
}
int main() {
int n;
cin >> n;
// 读取树的边并建立邻接表
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
// 从结点 1 开始 DFS 遍历,深度从 0 开始
dfs(1, -1, 0);
for (int i = 1; i <= n; i++) {
if (depth[i] % 2 == 0) {
cout << evenCnt << " ";
} else {
cout << oddCnt << " ";
}
}
return 0;
}