樹上亂搞 點分治

2022-05-02 05:00:08 字數 1293 閱讀 2511

poj - 1741 

給出一棵樹,詢問有多少個點路徑 <=k;

考慮點分治:

點分治:

解決大規模圖上路徑問題。

演算法流程:

考慮乙個樹上的路徑,只有兩種情況,經過根和不經過根,

1 . 經過根的路徑可以直接判斷 dis(u,v)=d(u)+d(v) ;

2 .  不經過根就找到那個根繼續遍歷分治下去求解。

找根的過程 : 如果鏈狀的樹,會直接退化到o(n^2) 因此每次對重心遍歷,保證複雜度

對於每乙個節點,統計穿過他的合法解,即      ans+=cal(rt,0);    

但這樣會有重複情況,在繼續統計子樹會出現問題,

因此           ans-=cal(v,w);

#include #include 

#include

#include

#include

using

namespace

std;

#define pb push_back

const

int n=1e4+5

;struct edgee[n*10

];int

ans,n,k,ecnt,root,max;

inthead[n],size[n],maxv[n];

vector

dis;

bool

vis[n];

void add(int u,int v,int

w)void

init()

void dfs_size(int u,int

fa)}

void dfs_root(int r,int u,int

fa)

for(int i=head[u];~i;i=e[i].next)

}void dfs_dis(int u,int fa,int

dir)

}int cal(int rt,int

d)

return

cur;

}void dfs(intu)}

intmain()

dfs(1);

printf(

"%d\n

",ans);

}//system("pause");

return0;

}//5 4//

1 2 3

//1 3 1

//1 4 2

//3 5 1

//0 0

view code

樹上亂搞 樹的重心

樹的重心 定義 即對於樹中每乙個節點,計算他所有子樹中節點數最大的點,這個值最小就是就重心。其實就是說 對於乙個無向圖,任選乙個點,把他搞成乙個樹,子樹裡節點數最大最小,這個點就是重心,因為使以重心為根建立樹更加平衡,樹的重心的性質 1 以樹的重心為根時,所有子樹的大小都不超過整棵樹大小的一半。因為...

分治思想及樹上點分治

分治思想在oi中是一種常見的思想。分治的基本思想是將乙個規模為n的問題分解為k個規模較小的子問題,這些子問題相互獨立且與原問題性質相同。求出子問題的解,就可得到原問題的解。即一種分目標完成程式演算法,簡單問題可用二分法完成。當我們求解某些問題時,由於這些問題要處理的資料相當多,或求解過程相當複雜,使...

樹上點分治入門

分治就是分而治之。額 好像這話已經被說爛了。學樹分治之前我們先來回顧下線性分治。一般的線性分治都是將大的區間分成多個小的區間 一般是兩個 然後將已處理好的小區間合併從而得到了這個大區間的結果,為了使分的次數盡可能少,應每次使分的小區間的大小盡可能平均,這樣分的次數就會是log級別的。好,現在我們要分...