1. 程式人生 > >洛谷3379最近公共祖先模板(dfs序)

洛谷3379最近公共祖先模板(dfs序)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。

輸入輸出格式

輸入格式:

第一行包含三個正整數N、M、S,分別表示樹的結點個數、詢問的個數和樹根結點的序號。

接下來N-1行每行包含兩個正整數x、y,表示x結點和y結點之間有一條直接連線的邊(資料保證可以構成樹)。

接下來M行每行包含兩個正整數a、b,表示詢問a結點和b結點的最近公共祖先。

輸出格式:

輸出包含M行,每行包含一個正整數,依次為每一個詢問的結果。

#include<bits/stdc++.h>
#define V (to[i])
#define N 500010
using namespace std;
int in1[N],out1[N],fa[N][25],dis[N],n,m,root,tot=0,ti=0;
int to[N<<1],head[N<<1],next[N<<1];
inline void add(int x,int y){
	tot+=1;
	next[tot]=head[x];
	to[tot]=y;
	head[x]=tot;
}
inline bool pd(int x,int y){
	return (in1[x]<=in1[y]&&out1[x]>=out1[y]);
}
inline void dfs(int x){
	in1[x]=++ti;//dfs序 
	for(int i=head[x];i;i=next[i]){
		if(fa[x][0]^V){//不是他的父親 
			fa[V][0]=x;
			dis[V]=dis[x]+1;//距離+1(距離越小越接近根節點) 
			dfs(V);//遞迴搜尋,這樣的話保證in1[V]>=in1[x]&&out1[V]<=out1[x] 
		}
	}
	out1[x]=++ti;
}
inline int get_lca(int x,int y){
	if(x==y)
		return x;//特判 
	if(dis[x]<dis[y])
		swap(x,y);//如果x在y上面交換 
	for(int i=20;~i;i--){
		if(!pd(fa[x][i],y))
			x=fa[x][i];//向上尋找 
	}
	x=fa[x][0];
	return x;
}
int main(){
	int x,y;
	scanf("%d%d%d",&n,&m,&root);
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	fa[root][0]=root;
	dfs(root);//從根開始深搜 
	for(int i=1;i<=20;i++){
		for(int j=1;j<=n;j++){
			fa[j][i]=fa[fa[j][i-1]][i-1];
		}
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&x,&y);
		printf("%d\n",get_lca(x,y));
	}
}




相關推薦

3379最近公共祖先模板dfs

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

3379 最近公共祖先模板倍增

#include<iostream> #include<cstdio> #include<cstring> #define maxn 500010 #define S

模板·LCA】3379 最近公共祖先LCA

思路:tarjan。 程式碼: #include <cstdio> #include <iostream> #include <algorithm>

lcaP3379 最近公共祖先LCA

int arc pragma rpi == 代碼 輸出 () div 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先. 輸入格式: 第一行包含三個正整數N、M、S,分別表示樹的結點個數、詢問的個數和樹根結點的序號。 接下來N-1行每行包含兩個正整數x、y

最近公共祖先-三RMQ-ST

描述 上上回說到,小Hi和小Ho使用了Tarjan演算法來優化了他們的“最近公共祖先”網站,但是很快這樣一個離線演算法就出現了問題:如果只有一個人提出了詢問,那麼小Hi和小Ho很難決定到底是針對這個詢問就直接進行計算還是等待一定數量的詢問一起計算。畢竟無論是一個詢問還是很多

【C++】最近公共祖先LCATarjan離線算法&& P3379LCA模板

target sizeof add 例題 開始 實現 再看 根節點 strong 1.前言   首先我們介紹的算法是LCA問題中的離線算法-Tarjan算法,該算法采用DFS+並查集,再看此算法之前首先你得知道並查集(盡管我相信你如果知道這個的話肯定是知道並查集的),

P3379 【模板最近公共祖先LCAdfs

log 輸出格式 sample namespace i++ 技術分享 規模 link wap P3379 【模板】最近公共祖先(LCA) 題目描述 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。 輸入輸出格式 輸入格式: 第一行包含三個正整數

lca最短公共祖先模板hdu2586

oid txt const .cn asf cli same class for 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<iostream> #include<c

順序儲存的二叉樹的最近公共祖先問題 25 分

順序儲存的二叉樹的最近的公共祖先問題 (25 分) 層次生成二叉樹 設順序儲存的二叉樹中有編號為i和j的兩個結點,請設計演算法求出它們最近的公共祖先結點的編號和值。 輸入格式: 輸入第1行給出正整數n(≤1000),即順序儲存的最大容量;第2行給出n個非負整數,其間以空格分隔。其

LCA 最近公共祖先 模板

Lca 離線演算法(tarjan演算法) 模板 #include<bits/stdc++.h> #define _ 1000100 using namespace std; char buf[1<<15],*fs,*ft; inline char getc()

浙大版《資料結構》習題4.5 順序儲存的二叉樹的最近公共祖先問題 25 分

設順序儲存的二叉樹中有編號為i和j的兩個結點,請設計演算法求出它們最近的公共祖先結點的編號和值。 輸入格式: 輸入第1行給出正整數n(≤1000),即順序儲存的最大容量;第2行給出n個非負整數,其間以空格分隔。其中0代表二叉樹中的空結點(如果第1個結點為0,則

luogu 3379 最近公共祖先 (線上倍增)

題目描述 如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。 輸入輸出格式 輸入格式: 第一行包含三個正整數N、M、S,分別表示樹的結點個數、詢問的個數和樹根結點的序號。 接下來N-1行每行包含兩個正整數x、y,表示x結點和y結點之間有一條直接連線的邊(

hihoCoder 1067 : 最近公共祖先·二map+離線Tarjan演算法

【思路分析】離線演算法是把所有的詢問先儲存起來,然後在深搜的過程中計算結果。本題本來就是一棵有根樹,應該先計算根節點是多少,然後再從根節點進行深搜。實現為+深搜+並查集。 【AC程式碼】 #

多叉樹最近公共祖先問題LCA

任務:設計一個演算法,對於給定的樹中兩結點,返回它們的最近公共祖先 輸入:第1行有一個正整數n,表示給定的樹有n個結點。結點編號為1,2,3,...,n,編號為1的頂點是樹根。接下來n行中,第i+1行描述了第i個結點的兒子情況。每行的第一個正整數k表示該結點有k個兒子,其後

P2532 [AHOI2012]樹屋階梯Catalan數

names images res main truct const () sizeof -1 P2532 [AHOI2012]樹屋階梯 題目描述 輸入輸出格式 輸入格式: 一個正整數N(1<=N<=50

P3200 [HNOI2009]有趣的數列Catalan數

整數 取模 排列 right 可能 滿足 奇數 cat using P3200 [HNOI2009]有趣的數列 題目描述 我們稱一個長度為2n的數列是有趣的,當且僅當該數列滿足以下三個條件: (1)它是從1到2n共2n個整數的一個排列{

】2822 組合數問題遞推

return bottom 初始化 list main sca set 如果 lld 題目描述 組合數C?n?m??表示的是從n個物品中選出m個物品的方案數。舉個例子,從(1,2,3) 三個物品中選擇兩個物品可以有(1,2),(1,3),(2,3)這三種選擇方法。根據組合

P2421 A-B數對增強版

clas pla back www pro fff 分答 left ins P2421 A-B數對(增強版) 題目背景 woshiren在洛谷刷題,感覺第一題:求兩數的和(A+B Problem)太無聊了,於是增加了一題:A-B Pro

——P2421 A-B數對增強版

++ 可能 復制 fin radi 輸入輸出格式 個數 -c () 題目背景 woshiren在洛谷刷題,感覺第一題:求兩數的和(A+B Problem)太無聊了,於是增加了一題:A-B Problem,難倒了一群小朋友,哈哈。 題目描述 給出N 個從小到大排好序的整

P3434 [POI2006]KRA-The Disks線段樹

def spa uil ref post 直觀 char getchar ++i 洛谷題目傳送門 \(O(n)\)的正解算法對我這個小蒟蒻真的還有點思維難度。洛谷題解裏都講得很好。 考試的時候一看到300000就直接去想各種帶log的做法了,反正不怕T。。。。。。 我永遠只