Borrow Classroom 最近公共祖先

2021-08-08 02:59:06 字數 1582 閱讀 8760

[程式設計題]borrow classroom

每年的bnu校賽都會有兩次賽前培訓,為此就需要去借教室,由於sk同學忙於出題,這個事情就由小q同學來跑腿。sk同學準備從宿舍出發,把借教室的單子交給小q同學讓他拿去教務處蓋章,但是何老師突然發現sk同學好像借錯教室了,想搶在借教室的單子被送到教務處之前攔截下來。

現在把校園抽象成一棵n個節點的樹,每條邊的長度都是乙個單位長度,從1到n編號,其中教務處位於1號節點,接下來有q個詢問,每次詢問中sk同學會從b號節點出發,到c號節點找到小q同學並將借教室的單子交給他,然後小q同學再從c號節點出發前往教務處,何老師會從a號節點出發開始攔截。

所有人在乙個單位時間內最多走乙個單位距離,只要何老師在單子還沒被送到教務處之前遇到拿著單子的同學都算攔截成功,如果小q同學已經到了教務處,那麼由於小q同學手速極快,單子會被立即交上去,即使何老師到了教務處也無濟於事,你需要判斷何老師是否能夠攔截成功。

輸入描述:

第一行是乙個正整數t(≤ 5),表示測試資料的組數, 對於每組測試資料, 第一行是兩個整數n,q(1≤ n,q ≤ 100000),分別表示節點數和詢問數, 接下來n-1行,每行包含兩個整數x,y(1≤ x,y ≤ n),表示x和y之間有一條邊相連,保證這些邊能構成一棵樹, 接下來q行,每行包含三個整數a,b,c(1 ≤ a,b,c ≤ n),表示乙個詢問,其中a是何老師所在位置,b是sk同學所在位置,c是小q同學所在位置,保證小q同學初始不在教務處。

輸出描述:

對於每個詢問,輸出一行,如果何老師能成功攔截則輸出"yes"(不含引號),否則輸出"no"(不含引號)。
示例1

1

7 21 2

2 33 4

4 71 5

1 63 5 6

7 5 6

yes

no

分別求出從b->c->1的路程bc 和 a->1 的路程a  如果 bca則一定可以攔截到,,如果bc=a 如果最後從c出發到達1和a不在同一顆子樹上則攔截失敗,也就是lca(a,c)==1時攔截失敗,否則在到達1之前a可以攔截。
#include using namespace std;

const int ax = 4e5+666;

struct node

node(){}

};std::vectorg[ax];

int ver[ax] , r[ax] , first[ax] , vis[ax];

int dp[ax][20];

int tot;

void dfs( int u , int dep ) }}

void st()

for( int j = 1 ; ( 1 << j ) <= tot ; j ++ ) }}

int rmq( int l , int r )

int main()

for( int i = 1 ; i < n ; i++ )

dfs( 1 , 1 );

st();

while( q-- )else

} }return 0;

}

最近公共祖先 python 最近公共祖先

lca演算法樸素演算法 也就是我們所說的暴力演算法,大致的思路是從樹根開始,往下迭代,如果當前結點比兩個結點都小,那麼說明要從樹的右子樹中找 相反則從左子樹中查詢 直到找到乙個結點在當前結點的左邊,乙個在右邊,說明當前結點為最近公共祖先,如果乙個結點是另外乙個結點的祖先,那麼返回前面結點的父親結點即...

最近公共祖先 LCA 最近公共祖先

直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...

最近公共祖先 最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...