Road Map

Solution-Road Map

题面

题目传送门

题意

给定一棵树,并给定一个根,现在要换一个根,求换根后每个点的父节点

输入:第一行 节点个数 原根 新根 第二行 除原根节点外每个节点的父节点

输出:除新根节点外每个节点的父节点

思路

建立一棵树?考虑用vector建树。 由于要换一个根,用dfs进行模拟。

这一道题没有太大的思维难度,只要把解题顺序捋清楚就行了:

  1. vector建立一棵树

建树部分代码:

g[u].push_back(v);
g[v].push_back(u);
  1. 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. 输出答案

从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;
}
posted @ 2023-05-21 11:13  _apologize  阅读(19)  评论(0)    收藏  举报  来源