题目来源:HLOJ
题目描述
给定一棵
n
n
n 个点的树,根为
t
t
t
求每个点的父亲是哪个点,
t
t
t 的父亲输出
0
0
0
输入格式
第一行两个整数
n
,
t
n,t
n,t
接下来
n
−
1
n−1
n−1 行,每行两个整数
x
,
y
x,y
x,y,表示
x
,
y
x,y
x,y 之间有一条边
输出格式
n n n 行,第 i i i 行一个整数,表示 i i i 号点的父亲
样例数据
input
4 3
1 3
3 2
1 4
output
3
3
0
1
数据规模与约定
1
≤
n
≤
105
1≤n≤105
1≤n≤105
时间限制:1s
空间限制:256MB
解题思路
- 想要 A C AC AC 这道题的前置技能: D F S DFS DFS 和 邻接表。
- 我们从根节点 t t t 开始 d f s dfs dfs , 并传两个参数: x x x 和 f a t h e r father father( x x x 表示当前点的编号, f a t h e r father father 表示当前点的父亲的编号),然后将 f a t h e r father father 赋值 给 f a [ x ] fa[x] fa[x]( f a [ x ] fa[x] fa[x] 表示 x x x 的父亲节点的编号),每次在邻接表中枚举与 x x x 号点相邻的点,如果枚举到的点事 x x x 号点的儿子, d f s dfs dfs 递归。
Code
#include <bits/stdc++.h>
using namespace std;
int n,t,tot=0;
int fa[100010],linkk[100010];
struct node
{
int y,next;
}e[200010];
void insert(int x,int y) //邻接表插入
{
e[++tot].y=y;
e[tot].next=linkk[x]; linkk[x]=tot;
}
void dfs(int x,int father)
{
fa[x]=father; //赋值
for (int i=linkk[x];i;i=e[i].next) //邻接表枚举
{
int y=e[i].y;
if (y!=father) //y号点是x的儿子
{
dfs(y,x); //递归
}
}
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%d %d",&n,&t);
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d %d",&x,&y);
insert(x,y); //无向图建边
insert(y,x);
}
dfs(t,0); //从根节点开始dfs
for (int i=1;i<=n;i++) printf("%d\n",fa[i]); //输出
return 0;
}