dfs序:是指將一棵樹被dfs時所經過的節點順序(不繞回原點)。
尤拉序:就是從根結點出發,按dfs的順序在繞回原點所經過所有點的順序。
通過dfs序判斷v節點的時間區間是否在u節點的時間區間內。
通過尤拉序求u和v的最近公共祖先。
dfs序:a-b-d-e-g-c-f-h
尤拉序:a-b-d-d-e-g-g-e-b-c-f-h-h-f-c-a
dfs序核心**
const
int maxn =
1e5+5;
vector<
int> g[maxn]
;//存放節點
int s[maxn]
, e[maxn]
;//s[maxn]存放「入時間戳」,e[maxn]存放「出時間戳」;
int n,id,len;
int dfsxu[
20000];
//存放dfs序
void
dfs(
int u,
int fa)
e[u]
= id;
}
dfs序完整**
#include
using namespace std;
const
int maxn =
1e5+5;
vector<
int> g[maxn]
;//存放節點
int s[maxn]
, e[maxn]
;//s[maxn]存放「入時間戳」,e[maxn]存放「出時間戳」;
int n,id,len;
int dfsxu[
20000];
//存放dfs序
void
dfs(
int u,
int fa)
e[u]
= id;
}int
main()
id =0;
dfs(1,
-1);
cout<<
"dfs序:"
;for
(int i=
1;s[i]!=0
;i++
) cout<
cout<<
"入時間戳:"
;for
(int i=
1;s[i]!=0
;i++
) cout<
cout<<
"出時間戳:"
;for
(int i=
1;e[i]!=0
;i++
) cout<
return0;
}
執行結果:
}核心**:
vector<
int> g[
40010];
//存放節點
int oulaxu[
80020];
//存放尤拉序在,在尤拉序中第一次出現為「入時間戳」,第二次出現為「出時間戳」。
int len;
void
dfs(
int u,
int fa)
oulaxu[
++len]
=u;}
完整**:
#include
#include
#include
#include
#include
#include
using namespace std;
vector<
int> g[
40010];
//存放節點
int oulaxu[
80020];
//存放尤拉序在,在尤拉序中第一次出現為「入時間戳」,第二次出現為「出時間戳」。
int len;
void
dfs(
int u,
int fa)
oulaxu[
++len]
=u;}
intmain()
for(
int i=
1; i<=n-
1; i++
)dfs(1
,0);
for(
int i=
1;i<=len;i++)}
}
執行結果
DFS序與尤拉序的區別
dfs序 是指將一棵樹被dfs時所經過的節點順序 不繞回原點 尤拉序 就是從根結點出發,按dfs的順序在繞回原點所經過所有點的順序。通過dfs序判斷v節點的時間區間是否在u節點的時間區間內。通過尤拉序求u和v的最近公共祖先。dfs序 a b d e g c f h 尤拉序 a b d d e g g...
雙重祖先(DFS序的應用)
dfs序 可以讓我們在 線性的陣列內 處理樹上的子樹等問題 所以我們只需要給第乙個樹 建立dfs序,然後用線段樹 或者樹狀陣列 維護一下就好了 第一棵樹的dfs序 第二顆樹 直接查詢 節點 3 的祖先 裡 哪些 也是第一棵樹的祖先 用線段樹 1.對兩個 1 節點區間 內所有數 1 2.對兩個 2 節...
選點 巧妙的dfs序dp
傳送門 注意一下這兩句話 如果選了根節點的話,在這棵子樹內選的其他的點都要比根節點的值大 如果在左子樹選了乙個點,在右子樹中選的其他點要比它小。根節點比子節點都要小 右子樹比左子樹都要大 所以可以跑dfs dfsdf s序維護最長上公升子串行來寫 include using namespace st...