點分治入門 樹中點對距離詳(?)解

2021-10-01 07:35:00 字數 864 閱讀 7816

其中樹最多有10000個點,len<=maxlongint

這是一道模板題目。

對於乙個點x,我們考慮如何求解經過x點的路徑方案數,設為f(x)。

考慮直接從x出發做一遍dfs,算出所有未到過的點到x點的距離,然後排序。

設兩個指標,如果length[l]+length[r]<=len,那麼length[l]+length[x](l統計答案結束。

怎麼可能結束了呢?這樣計算肯定會有不經過x點的路徑答案啊!

在計算f(son(son為x的兒子))時,由於x點已經經過,算答案時x點相當於斷掉的開關,所以算出的答案路徑一定不經過x,減去即可。

每次都挑重心去遞迴,這樣每棵子樹大小至多為原來的一半,只需遞迴n log n層

快排log n複雜度,總時間複雜度o(n log^2 n)

code

#include #include #include using namespace std;

int i,j,k,m,n,o,p,l,s,t,maxlen,tot,cent,ans;

int f[20005][4],q[20005],size[20005],bz[20005],son[20005];

long long len[20005];

void insert(int x,int y,int z)

void getlen(int t,int fa,int lenn)

}int work(int t,int lenn)

son[t]=max(son[t],tot-size[t]);

if (son[t]}void dg(int t)

}int main()

樹中點對距離(點分治)

給出一棵帶邊權的樹,問有多少對點的距離 len 這是一道點分治的經典題目,可以給點分治的初學者練手。點分治,顧名思義就是把每個點分開了處理答案。假設,目前做到了以x為根的子樹。先求出子樹中每個點到根的距離di s 對於兩個點 i 和 j,如果di si d isj k 那麼 i j 就是乙個合法的點...

點分治模板 (樹中點對距離)

點分治就是在一棵樹中,將每個點分治 基本概念 點分治 將一棵無根樹變成有根樹,再分別處理每棵有根子樹。重心 在一棵樹中,這個點的最大子樹是所有點中最小的。也可以說是刪除該點時,樹內剩下的子樹最大節點數最小。size i 表示以i為根的子樹節點數量。如何求重心?求出size,什麼是定義,就怎麼求。一般...

jzoj1166 樹中點對距離 點分治

求一棵樹上有多少條路徑長度 le n leq len len 首先普通點分治。掃瞄的時候將每個點儲存為乙個二元組 di s,gr a dis,gra dis,g ra 分別表示離 分治到的 根的距離,屬於根的那顆子樹。然後按照dis disdi s排序,兩個指標l,r l,rl,r用cn icn i...