问题描述
可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索
自己的手机。
现在我们假设 Bibi 的家位于一棵二叉树的根部。在 Bibi 的心中,每个节点
都有一个权值 x,代表他心中预感向这个节点走可能找回自己手机的程度(虽然
他的预感根本不准)。 当 Bibi 到达一个节点时,如果该节点有未搜索过的儿子节
点,则 Bibi 会走向未搜索过的儿子节点进行搜索,否则就返回父亲节点。 如果
某节点拥有两个未搜索过的儿子节点, Bibi 会选择先搜索权值大的儿子节点。
假设 Bibi 从一个节点到达另一个节点需要 1 单位时间,搜索节点的时间忽
略不计,那么请问当 Bibi 的手机位于编号为 k 的节点时,他需要多少单位时间
才能找到手机。
★ 数据输入
输入第一行为一个正整数 n(1≤n≤100000) 表示树的节点数目,树根的编号
总是为 1。
接下来 n-1 行, 每行两个正整数 p, x(1≤x≤100)。 代表编号为 i 的节点的父
亲节点 p 和权值 x。这里的 i 从 2 依次数到 n。 数据保证输入的 p 小于当前的 i,
且互为兄弟的两个节点的权值 x 不同。
第 n+1 行一个整数 m(1≤m≤n), 表示询问组数。
第 n+2 行有 m 个整数,每个整数 ki(1≤ki≤n) 代表该组询问中手机的位置。
★ 数据输出
输出 m 行, 每行一个整数,代表 Bibi 找到手机需要花费的单位时间数量。
输入示例 | 输出示例 |
3 1 20 1 30 3 1 2 3 |
0 3 1 |
解题思路
二叉树dfs走一遍
应注意的是对于每一个节点,进入节点与退出节点step都应+1
code
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Node { Node(){} int weight; int step; int left; int right; }; Node *arr = NULL; int step = 0; void dfs(int index) { arr[index].step = step; ++step; if(arr[index].left==0) { } else if(arr[index].right==0) { dfs(arr[index].left); } else if(arr[arr[index].left].weight > arr[arr[index].right].weight) { dfs(arr[index].left); dfs(arr[index].right); } else { dfs(arr[index].right); dfs(arr[index].left); } ++step; } int main() { int i; int n,m,k; scanf("%d",&n); arr = (Node *)malloc(sizeof(Node)*(n+1)); memset(arr,0,sizeof(Node)*(n+1)); int fa_index,weight; for(i=2;i<=n;i++) { scanf("%d %d",&fa_index,&weight); if(arr[fa_index].left==NULL) arr[fa_index].left = i; else // (arr[fa_index].left!=NULL) arr[fa_index].right = i; arr[i].weight = weight; } dfs(1); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d",&k); printf("%d ",arr[k].step); } free(arr); return 0; }