★實驗任務
現有一個樹形的消息通信系統,當節點 i 要發送消息時,它會查找它的子節
點,向還沒發送過消息的子節點發送消息,如果有多個這樣的子節點,則優先選
擇節點編號最小的節點,而它的子節點也以同樣的策略向下傳送消息。當節點 i
的某個子節點完成了消息發送任務後,節點 i 繼續查找剩餘還沒發送過消息的子
節點發送消息,直到節點 i 已經向所有的子節點發送過消息了,則節點 i 完成了
它的消息發送任務。
現有 q 次詢問,每次給出一個節點編號 u 和整數 k,問從節點 u 開始發送消
息,則第 k 個收到消息的節點的編號是多少,如果不存在這樣的節點,則輸出
“-1”。
★數據輸入
第一行包含兩個整數 n 和 q,表示樹中的節點數(2≤n≤2·10^5)和詢問的
次數(1≤q≤2·10^5)。
接下來的一行包含 n-1 個整數 pi(1≤i≤n-1) 表示第 i + 1 個節點的父節點
的下標(1≤pi≤i)。節點 1 是根節點。
接下來 q 行,每行兩個整數 u 和 k(1≤u, k≤n),u 是開始傳播消息的節點
編號,k 表示詢問第 k 個收到消息的節點。
★數據輸出
輸出 q 行,每行表示第 q 次詢問的節點編號,如果不存在這樣的節點,則
輸出“-1”。
輸入示例 輸出示例
9 6
1 1 1 3 5 3 5 7
3 1
1 5
3 4
7 3
1 8
1 9
輸出:
3
6
8
-1
9
4
代碼還沒還沒試過,如果沒過再來改如果過了就不改了
這裏採用兒子鏈表表示法來表示這棵樹,開一一個數組,數組元素存的內容是節點的父節點,然後又從節點引出一個兒子鏈表。
遍歷方式:遞歸地遍歷,當到達每個節點時,查看有沒有兒子鏈表,有則查看兒子節點,沒有則返回(說明此節點是葉節點)。如此遞歸地遍歷樹,這題暫時沒想出好的做法,只能暴力模擬了≡(▔﹏▔)≡。
代碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#pragma warning(disable:4996)
#define sf scanf
#define pf printf
#define sf2d(x,y) scanf("%d %d",&(x),&(y))
#define sfd(x) scanf("%d",&x)
#define sff(p) scanf("%lf",&p)
#define pfd(x) printf("%d\n",x)
#define mset(x,b) memset((x),b,sizeof(x))
/*
兒子鏈表表示法表示樹
*/
struct Node {//
int number;//數組存的是父親位置,鏈表存的是自己的位置
Node* next;
Node(int num):number(num),next(0){}
Node() :number(0), next(0) {}
};
struct Pto {
Node *p;
Pto() :p(0){}
};
Node head[200010];
Pto tail[200010];
void Travel(int sta, int& stp,int aim) {
if (stp == aim) {//到達目標步數
pfd(sta);
return;
}
if (head[sta].next == 0)
return;
else {
Node* p=head[sta].next;
while (p&&stp<aim) {
stp++;//步數加一
Travel(p->number, stp, aim);//訪問節點
p = p->next;
}
}
return;
}
int main(void) {
int n, q;
int temp;
Node *ptr=0;
sf2d(n, q);
for (int i = 2; i <= n; i++) {
sfd(temp);
head[i].number = temp;//記錄父親 ///把temp存進i裏面
ptr = new Node(i);//i爲自己的編號
//把i存進temp裏面
if (tail[temp].p == 0) {//纔有第一個兒子
head[temp].next = tail[temp].p = ptr;
ptr->next = 0;
}
else {
tail[temp].p->next = ptr;
tail[temp].p = ptr;
ptr->next = 0;
}
}
int sta, stp,aim;
for (int j = 0; j < q; j++) {
sf2d(sta,aim);
stp = 1;
Travel(sta, stp, aim);
if (stp < aim)
pfd(-1);
}
return 0;
}