poj - 1741
給出一棵樹,詢問有多少個點路徑 <=k;
考慮點分治:
點分治:
解決大規模圖上路徑問題。
演算法流程:
考慮乙個樹上的路徑,只有兩種情況,經過根和不經過根,
1 . 經過根的路徑可以直接判斷 dis(u,v)=d(u)+d(v) ;
2 . 不經過根就找到那個根繼續遍歷分治下去求解。
找根的過程 : 如果鏈狀的樹,會直接退化到o(n^2) 因此每次對重心遍歷,保證複雜度
對於每乙個節點,統計穿過他的合法解,即 ans+=cal(rt,0);
但這樣會有重複情況,在繼續統計子樹會出現問題,
因此 ans-=cal(v,w);
#include #includeview code#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
樹上亂搞 樹的重心
樹的重心 定義 即對於樹中每乙個節點,計算他所有子樹中節點數最大的點,這個值最小就是就重心。其實就是說 對於乙個無向圖,任選乙個點,把他搞成乙個樹,子樹裡節點數最大最小,這個點就是重心,因為使以重心為根建立樹更加平衡,樹的重心的性質 1 以樹的重心為根時,所有子樹的大小都不超過整棵樹大小的一半。因為...
分治思想及樹上點分治
分治思想在oi中是一種常見的思想。分治的基本思想是將乙個規模為n的問題分解為k個規模較小的子問題,這些子問題相互獨立且與原問題性質相同。求出子問題的解,就可得到原問題的解。即一種分目標完成程式演算法,簡單問題可用二分法完成。當我們求解某些問題時,由於這些問題要處理的資料相當多,或求解過程相當複雜,使...
樹上點分治入門
分治就是分而治之。額 好像這話已經被說爛了。學樹分治之前我們先來回顧下線性分治。一般的線性分治都是將大的區間分成多個小的區間 一般是兩個 然後將已處理好的小區間合併從而得到了這個大區間的結果,為了使分的次數盡可能少,應每次使分的小區間的大小盡可能平均,這樣分的次數就會是log級別的。好,現在我們要分...