dfs序是用來處理子樹一類問題的,可以把子樹問題轉化為區間問題,以便借助線段樹或樹狀陣列處理。根據dfs的順序來給節點編號,在進入這個節點時更新in陣列,出去的時候更新out陣列,這樣以i為根的子樹的操作就可以變成區間[in[i]…out[i]]的操作了。
int in[
100005
],out[
100005];
int tot =1;
void
dfs(
int x,
int fa)
out[x]
= tot -1;
}
題目:給定一棵以1為根的樹,有兩種操作。操作1將節點的x的權值異或1,操作2詢問以x為根的子樹的節點權值和。
思路:利用dfs序將子樹詢問變為區間和,樹狀陣列維護即可。
#include
#include
using
namespace std;
vector<
int> g[
100005];
int n,num[
100005];
int in[
100005
],out[
100005
],c[
100005];
int tot =1;
void
dfs(
int x,
int fa)
out[x]
= tot -1;
}int
lowbit
(int x)
void
update
(int x,
int k)
}int
query
(int x)
return res;
}int
main()
dfs(1)
;for
(int i =
1; i <= n; i++
)int m;
scanf
("%d"
,&m)
;for
(int i =
1; i <= m; i++
)else
else}}
return0;
}
雙重祖先(DFS序的應用)
dfs序 可以讓我們在 線性的陣列內 處理樹上的子樹等問題 所以我們只需要給第乙個樹 建立dfs序,然後用線段樹 或者樹狀陣列 維護一下就好了 第一棵樹的dfs序 第二顆樹 直接查詢 節點 3 的祖先 裡 哪些 也是第一棵樹的祖先 用線段樹 1.對兩個 1 節點區間 內所有數 1 2.對兩個 2 節...
uva 10765 dfs及其應用
題意 乙個無向連通圖刪除某點後分成的連通塊個數成為該點的鴿子值。求鴿子值最大的m個點的鴿子值 思路 1.鴿子值 1 該點是割點。2統計割點所連線的點雙連通分量。tarjan演算法求割點過程中,改標記割點為統計該點所連線的點雙連通分量個數即可。include include include inclu...
DFS及其剪枝
深度優先搜尋,是從初始狀態起,利用一定的規則生成搜尋樹,尋找下一層任乙個結點,檢查是否出現目標狀態,若未出現,以此狀態利用規則生成再下一層任乙個結點,再檢查,重複過程一直到葉節點 即不能再生成新狀態節點 當它仍不是目標狀態時,回溯到上一層結果,取另一可能擴充套件搜尋的分支。採用相同辦法一直進行下去,...