测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A28364. 树上漫步

填空题 困难

题目描述

树上漫步

题目描述

小 A 有一棵n个结点的树,这些结点依次以1,2,...,n 标号。

小 A 想在这棵树上漫步。具体来说,小 A 会从树上的某个结点出发,每一步可以移动到与当前结点相邻的结点,并且小 A 只会在偶数步(可以是零步)后结束漫步。

现在小 A 想知道,对于树上的每个结点,从这个结点出发开始漫步,经过偶数步能结束漫步的结点有多少个(可以经过重复的节点)。

输入格式

第一行,一个正整数n 。

接下来n-1行,每行两个整数ui,vi ,表示树上有一条连接结点ui 和结点vi  的边。

输出格式

一行, n个整数,第 i个整数表示从结点i出发开始漫步,能结束漫步的结点数量。

样例

输入样例 1

3
1 3
2 3

输出样例 1

2 2 1

输入样例 2

4
1 3
3 2
4 3

输出样例 2

3 3 1 3 

数据范围

对于 40% 的测试点,保证1≤n≤103 。

对于所有测试点,保证 1≤n≤2×105。

参考答案

#include <cstdio> #include <algorithm> using namespace std; const int N = 2e5 + 5; const int E = N << 1; int n; int h[N], to[E], nx[E], et; int cnt[N], bel[N]; void ae(int u, int v) { et++; to[et] = v; nx[et] = h[u]; h[u] = et; } void dfs(int u, int c, int f) { bel[u] = c; cnt[c]++; for (int i = h[u]; i; i = nx[i]) if (to[i] != f) dfs(to[i], c ^ 1, u); } int main() { scanf("%d", &n); for (int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); ae(u, v); ae(v, u); } dfs(1, 0, 0); for (int i = 1; i <= n; i++) printf("%d%c", cnt[bel[i]], " \n"[i == n]); return 0; }
上一题 下一题