[GESP202503 六级] 树上漫步(含视频)

视频讲解:GESP202503 六级 树上漫步-信息学奥赛GESP等级考试真题解析

一、原题

题目描述

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

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

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

输入格式

第一行,一个正整数 n。

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

输出格式

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

输入输出样例

输入 #1

cpp 复制代码
3
1 3
2 3

输出 #1

cpp 复制代码
2 2 1

输入 #2

cpp 复制代码
4
1 3
3 2
4 3

输出 #2

cpp 复制代码
3 3 1 3

说明/提示

对于 40% 的测试点,保证 1≤n≤10^3。

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

二、做题思路

1)填充数据

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>>g;
int main(){
	//1)填充数据
	//1.1)确定节点数量n
	int n;cin>>n; 
	//1.2)填充n-1条边的链接情况 
	for(int i=1;i<=n-1;i++){
		int u,v;cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	return 0; 
}

2)深搜:计算奇/偶数高度的节点数量

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>>g;
bool vis[200005];
int d[200005];
int total[2];
//2.2)深搜每个结点
void dfs(int x,int deep){
	//2.4)计算奇数偶数结点数量 
	total[deep%2]++;
	//2.5)标记当前结点的高度
	d[x]=deep;
	vis[x]=1;
	for(auto it:g[x]){
		if(vis[it]==0){
			//2.3)计算当前结点高度
			dfs(it,deep+1);
		}
	}
}
int main(){
	//1)填充数据
	//... 
	//2)深搜:计算奇/偶数高度的节点数量
	//2.1)从结点1开始深搜 
	dfs(1,1);
	return 0; 
}

3)输出结果

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>>g;
bool vis[200005];
int d[200005];
int total[2];
//2.2)深搜每个结点
void dfs(int x,int deep){
	//2.4)计算奇数偶数结点数量 
	//....
	//2.5)标记当前结点的高度
	//...
			//2.3)计算当前结点高度
			//...
}
int main(){
	//1)填充数据
	//... 
	//2)深搜:计算奇/偶数高度的节点数量
	//2.1)从结点1开始深搜 
	dfs(1,1);
	//3)输出结果
	for(int i=1;i<=n;i++){
		//结点高度是奇数,输出奇数总数 
		if(d[i]%2==1) cout<<total[1]<<" ";
		//结点高度是偶数,输出奇数偶数 
		else cout<<total[0]<<" ";
	}
	return 0; 
}

三、答案

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
map<int,vector<int>>g;
bool vis[200005];
int d[200005];
int total[2];
//2.2)深搜每个结点
void dfs(int x,int deep){
	//2.4)计算奇数偶数结点数量 
	total[deep%2]++;
	//2.5)标记当前结点的高度
	d[x]=deep;
	vis[x]=1;
	for(auto it:g[x]){
		if(vis[it]==0){
			//2.3)计算当前结点高度
			dfs(it,deep+1);
		}
	}
}
int main(){
	//1)填充数据
	//1.1)确定节点数量n
	int n;cin>>n; 
	//1.2)填充n-1条边的链接情况
	for(int i=1;i<=n-1;i++){
		int u,v;cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	//2)深搜:计算奇/偶数高度的节点数量
	//2.1)从结点1开始深搜 
	dfs(1,1);
	//3)输出结果
	for(int i=1;i<=n;i++){
		//结点高度是奇数,输出奇数总数 
		if(d[i]%2==1) cout<<total[1]<<" ";
		//结点高度是偶数,输出奇数偶数 
		else cout<<total[0]<<" ";
	}
	return 0; 
}
相关推荐
Purple Coder1 小时前
南京-我来啦
算法
w_zero_one1 小时前
动态规划(三)
java·算法·动态规划
Logic1011 小时前
C语言/数据结构贡献法题解:数组权值——所有连续子数组中不同数字个数之和(O(n)解法)
c语言·数据结构·算法·数组·时间复杂度·贡献法·哈希记录
DongQiShanRen1 小时前
六根硬件映射(中):双站校验、生克闭环与驱动接口
数据库·人工智能·算法·rust·哈希算法·集成学习
mmmmath_32 小时前
LeetCode.637.二叉树的层平均值
算法·leetcode
青少儿编程课堂2 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会C/C++考级:并查集连通块与朋友圈问题解析
c++·python·算法·bfs·信息学竞赛
Tisfy2 小时前
LeetCode 2913.子数组不同元素数目的平方和 I:第一题先常数很大的O(n^2)
算法·leetcode·题解·模拟·暴力
罗湖老棍子2 小时前
[USACO05NOV] Asteroids G(洛谷-P7368)
算法·图论·二分图匹配·最大匹配·最小顶点覆盖
AI技术新视界2 小时前
Harness^2:递归自进化智能体Harnessing框架
人工智能·深度学习·算法·harness·rsi