求樹上倆結點之間距離小於k的結點對個數;
倆個點a,b的公共祖先為c,那麼這倆個點的距離就可以用dis(a,c)+dis(b,c)表示,我們可以不斷的處理這樣c,然後計算距離,處理點對,為了使平均效能最好,我們需要找的c為每一棵子樹的重心;需要注意的算點對的時候這種方法成立的條件是倆個點不在同一顆子樹上,因此我們算完以後還需要減去在乙個子樹的點對;
然後解釋一下**,**是學習的網上大牛的,一起學習吧;
#include#include#includeusing namespace std;
#define maxn 10010
int cnt,head[maxn];
bool vis[maxn];
int size[maxn],dp[maxn];// 子樹的結點個數,子樹最大結點個數
int dis[maxn],ans;//結點到根的距離陣列;
int n,k;
int mid,root,num;//最小結點數用來找重心,重心,點對數
struct edgeedge[2*maxn];
void init()
void addedge(int u,int v,int w)
void dfssize(int u,int f) //找重心,這裡不能像找一棵樹的重心一樣直接用乙個vis陣列 }}
void dfsroot(int u,int v,int f) //用來找重心,第一引數是樹根,第二個是當前結點,第三個為父親結點
return ret;
}void dfs(int u) //樹的分治 }}
int main()
dfs(1);
printf("%d\n",ans);
}}
poj 1741 Tree 樹的分治
解 文中有,就是把路徑分成經過樹根,和不經過樹根兩類,每次處理經過樹根的,然後剩下的子樹部分可以遞迴處理,如果每次選取樹的重心,那麼可以保證最多遞迴logn層。經過樹根的先排序,然後o n 的複雜度就能算出,那麼每層的複雜度nlogn,最多遞迴logn層,總複雜度nlogn 2 include in...
POJ 1741 Tree 樹的分治
題目 題意 給定一棵樹,有n個點和n 1條邊,邊有邊權,給出乙個k,求樹上任意兩點間的最短距離不大於k的個數 思路 看了09年漆子超的 利用分治法,每次找樹的重心,重心即是在當前樹中刪掉此點後,節點數最多的子樹的節點數最小,找到重心後,求其所有子孫到其的距離,然後統計一下兩兩之和不大於k的個數,另外...
POJ 1741 Tree (樹的分治)
給定一棵樹,計算長度不超過 k的鏈的個數 樹分治入門題,看著題解刷的 選定乙個點,首先一條鏈要麼在此點的子樹上 要麼這條鏈經過這個點 在子樹上就可以劃分為子問題,然後分治處理 經過這個點的鏈,可以把子樹上的點到根的距離處理出來 然後對這些距離排個序,就能 o n 統計 選點要選重心,重心的所有子樹大...