資料結構小測(題目解析)Problem C
Problem C
時限:1s 記憶體:32M
★實驗任務
可憐的 Bibi 剛剛回到家,就發現自己的手機丟了,現在他決定回頭去搜索自己的手機。
現在我們假設 Bibi 的家位於一棵二叉樹的根部。在 Bibi 的心中,每個節點都有一個權值 x,代表他心中預感向這個節點走可能找回自己手機的程度(雖然他的預感根本不準)。當 Bibi 到達一個節點時,如果該節點有未搜尋過的兒子節點,則 Bibi 會走向未搜尋過的兒子節點進行搜尋,否則就返回父親節點。如果某節點擁有兩個未搜尋過的兒子節點,Bibi 會選擇先搜尋權值大的兒子節點。
假設 Bibi 從一個節點到達另一個節點需要 1 單位時間,搜尋節點的時間忽略不計,那麼請問當 Bibi 的手機位於編號為 k 的節點時,他需要多少單位時間才能找到手機。
★資料輸入
輸入第一行為一個正整數 n,表示樹的節點數目,樹根的編號總是為 1。接下來 n-1 行,每行兩個正整數 p,x,代表編號為 i 的節點的父親節點 p 和
權值 x。這裡的 i 從 2 依次數到 n。
資料保證輸入的 p 小於當前的 i,且互為兄弟的兩個節點的權值 x 不同。第 n+1 行一個整數 m,表示詢問組數。
第 n+2 行有 m 個整數,每個整數 ki 代表該組詢問中手機的位置。
★資料輸出
輸出 m 行,每行一個整數,代表 Bibi 找到手機需要花費的單位時間數量。
輸入示例 |
輸出示例 |
3 |
0 |
1 20 |
3 |
1 30 |
1 |
3 |
|
1 2 3 |
|
★資料範圍與約定
對於 30%的資料,1 <= n <= 100,1 <= m <= 100。 對於 60%的資料,1 <= n <= 2000,1 <= m <= 2000。
對於 100%的資料,1 <= n <= 100000,1 <= m <= 100000,1 <= x <= 100,
1 <= ki <= n。
這題沒有什麼技巧性,按題意走就行
首先順序建樹,然後遞迴尋路,詢問輸出。
#include <cstdio>
using namespace std;
//初始化樹節點
struct Node{
int weight;
int right,left;
Node (int r=0,int l=0,int w=0):right(r),left(l),weight(w){
}
}t[100005];
int k[100005];//存下每一個節點的步數
int DFS(int x,int time)
{
if (x==0)
return (time-1);//這裡沒兒子,不應該走,消去回程的步數
if (x!=1)
time++;
k[x]=time;
int cl=0,cr=0;//搜尋標記
int l=t[x].left,r=t[x].right;
//先搜尋兒子節點權值大的;
if (t[l].weight>t[r].weight&&cl==0)
{
time=DFS(l,time);
time++;
cl=1;
}
else if (t[r].weight>t[l].weight&&cr==0)
{
time=DFS(r,time);
time++;
cr=1;
}
//搜完權值大的兒子後,再搜尋未搜尋過的兒子
if (cl==0)
{
time=DFS(l,time);
time++;
cl=1;
}
if (cr==0)
{
time=DFS(r,time);
time++;
cr=1;
}
return time;
}
int main()
{
int n,p,x,m,ki;
scanf ("%d",&n);
for (int i=2;i<=n;i++)
{
scanf ("%d%d",&p,&x);
t[i].weight=x;
if (t[p].left==0)
{
t[p].left=i;
}
else if (t[p].right==0)
{
t[p].right=i;
}
}
DFS(1,0);
scanf ("%d",&m);
for (int i=0;i<m;i++)
{
scanf ("%d",&ki);
printf ("%d\n",k[ki]);
}
return 0;
}