this way
點分治模板
點分治解決的好像大部分是樹上路徑問題
網上模板有很多,我就不贅述了,大致思想就是找到樹的重心,然後o(n)地求出路徑經過這個點的所有情況,之後再將樹以這個重心為基準分成多個子樹,再找到他們的重心,如此分治的去做。網上的**各不相同,我找了同集訓隊的人的寫法,用set維護每個值是否出現,總的時間複雜度大概是o(n
log2
n)
o(nlog^2n)
o(nlog
2n)?
#include
using
namespace std;
const
int n=
1e4+
5,m=
105;
struct edgee[n*
2];int cnt,head[n]
;void
add(
int x,
int y,
int v)
int n,m,ans[m]
,q[m];
bool vis[n]
;//當前連通塊是否被處理過了
int rt,mx,all,siz[n]
;//重心,最大子樹大小,當前連通塊大小,子樹大小
void
f_rt
(int x,
int fa)
mx_sub=
max(mx_sub,all-siz[x]);
if(mx_sub
rt=x,mx=mx_sub;
}int dis[n]
;set
<
int>st,tmp;
void
f_dis
(int x,
int fa,
int v)
}void
cal(
int x)}}
for(
int i:tmp)st.
insert
(i);
tmp.
clear()
;}}void
divide
(int x,
int tot)
}int
main()
洛谷 P3806 模板 點分治1
洛谷傳送門 給定一棵有 nn 個點的樹,詢問樹上距離為 kk 的點對是否存在。第一行兩個數 n,mn,m。第 22 到第 nn 行,每行三個整數 u,v,wu,v,w,代表樹上存在一條連線 uu 和 vv 邊權為 ww 的路徑。接下來 mm 行,每行乙個整數 kk,代表一次詢問。對於每次詢問輸出一行...
洛谷 P3806 模板 點分治1
感謝hzwer的點分治互測。給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。輸入格式 n,m 接下來n 1條邊a,b,c描述a到b有一條長度為c的路徑 接下來m行每行詢問乙個k 輸出格式 對於每個k每行輸出乙個答案,存在輸出 aye 否則輸出 nay 不包含引號 輸入樣例 1 複製2 1 1 ...
洛谷 P3806 模板 點分治1 點分治
傳送門 點分治!點分治.滾,雖然也沒有可以講的扣就完事了理解好就行 這裡講一下自己計算答案時的乙個部分,我們設tti tt i tti 表示到當前重心的距離為i ii的路徑是否存在 對於每個詢問q iq i qi 因為我們便利完前面的i 1 i 1i 1棵子樹,所以用ttq i itt ttqi i...