1. 程式人生 > >資料結構小測(題目解析)Problem C

資料結構小測(題目解析)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;
}