其中樹最多有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...