Road Map
Solution-Road Map
题面
题意
给定一棵树,并给定一个根,现在要换一个根,求换根后每个点的父节点
输入:第一行 节点个数 原根 新根 第二行 除原根节点外每个节点的父节点
输出:除新根节点外每个节点的父节点
思路
建立一棵树?考虑用vector建树。 由于要换一个根,用dfs进行模拟。
这一道题没有太大的思维难度,只要把解题顺序捋清楚就行了:
- 用vector建立一棵树
建树部分代码:
g[u].push_back(v);
g[v].push_back(u);
- dfs进行换根
以 b 为根,并让 b 的父亲为0,进行dfs。每次dfs一个节点时记录这个节点的上一个父亲节点。这个父亲节点就是最终这个节点的答案。
dfs部分代码:
void dfs(int x,int fa){
Fa[x]=fa;
for(int i=0;i<g[x].size();i++){
int v=g[x][i];
if(v!=fa)dfs(v,x);
}
}
dfs(b,0);
- 输出答案
从1~n依次输出答案,如果这个节点的父亲节点为0,那么证明这个节点为根,需跳过。 答案输出部分代码:
for(int i=1;i<=n;i++){
if(i!=b)printf("%d ",Fa[i]);
}
完整代码(附带详细注释)
//核心思路:换根
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
vector<int>g[N];//用vector建树
int Fa[N];//每个节点的父亲节点
int a,b,n;
void dfs(int x,int fa){//x代表当前遍历到的节点,fa表示节点x的上一个遍历节点,即x的父亲节点
Fa[x]=fa;//用数组Fa[]记录节点x的父亲节点为fa
for(int i=0;i<g[x].size();i++){//开始遍历与x相连的每个节点
int v=g[x][i];//用v记录与x相连的每个节点
if(v!=fa){//如果这个相连的节点不等于它的父亲,注意这里很重要!!!防止陷入死循环
dfs(v,x);//继续dfs,现在v是当前节点,x是v的父亲节点
}
}
}
int main(){
scanf("%d%d%d",&n,&a,&b);//输入
for(int i=1;i<=n;i++){
if(i==a)continue;//如果这个节点为原来的根节点a那么就得跳过
int x;
scanf("%d",&x);
g[x].push_back(i);//用vector建树
g[i].push_back(x);//每次链接两条边
}
dfs(b,0);//以新的根节点b进行遍历,注意这里根节点的父亲为0
for(int i=1;i<=n;i++){
if(i!=b)printf("%d ",Fa[i]);//输出每个除新的根节点外的节点的父亲节点
}
return 0;
}

浙公网安备 33010602011771号