☰
[GESP202503 六级] 树上漫步(含视频)
2026/10/16 9:32:12 网站建设 项目流程

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

一、原题

题目描述

小 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≤10^3。

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

二、做题思路

1)填充数据

#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)深搜:计算奇/偶数高度的节点数量

#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)输出结果

#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; }

三、答案

#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; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询