[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; 
}
相关推荐
机器人零零壹14 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
ZhengEnCi16 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱
算法
取名真是17 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
罗西的思考17 小时前
【轻量化复刻大模型 / KIMI K3】KDA 模块交互式演示
人工智能·算法·机器学习
nm_zfyjt19 小时前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)
算法·重构·内蒙古朋友圈广告服务商·内蒙古朋友圈获客
w_zero_one21 小时前
算法--构造
java·数据结构·算法
其实防守也摸鱼21 小时前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php
小超人诞生日记1 天前
C++ 智能指针的使用及其原理详解
c++·算法
AiNightVision1 天前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件