POJ1741Tree 樹形dp 樹分治

2021-07-30 17:01:14 字數 909 閱讀 5765

題目大意:給一棵邊帶權樹,問兩點之間的距離小於等於k的點對有多少個。

具體題解看**。

#include#include#include#includeusing namespace std;

const int maxn = 21000;

struct node

tree[maxn], *head[maxn], tp[maxn];

bool vis[maxn];

int dist[maxn], size[maxn], sign[maxn];

int ans, ptr, root, n, k, tot;

//ans為所求答案,ptr邊的計數

void addedge(int u, int v, int w)

void dfs(int x, int past)//求樹的重心

p = p->nxt;

}tp[x].sum++;//加上根節點

sign[tot] = x;//記錄下這個節點

size[tot++] = tp[x].maxn;//該節點最大子樹的節點個數

}int getroot(int x)

}return maxsign;

}void calcdist(int s, int past, int dis)//計算各個點到當前根節點的距離

}void countsum(int x)

}void countdel(int x)

}p = p->nxt;

}}void deal(int s, int past)//s當前點,past父節點

}int main()

deal(1, 0);

printf("%d\n", ans);

}return 0;

}

樹形 點分治 POJ 1741 Tree

通道 題意 有多少對 u,v 的距離小於k 思路 將無根樹轉化成有根樹進行觀察。滿足條件的點對有兩種情況 兩個點的路徑橫跨樹根,兩個點位於同一顆子樹中。如果我們已經知道了此時所有點到根的距離a i a x a y k的 x,y 對數就是結果,這個可以通過排序之後o n 的複雜度求出。然後根據分治的思...

poj 1741 Tree 樹的分治

解 文中有,就是把路徑分成經過樹根,和不經過樹根兩類,每次處理經過樹根的,然後剩下的子樹部分可以遞迴處理,如果每次選取樹的重心,那麼可以保證最多遞迴logn層。經過樹根的先排序,然後o n 的複雜度就能算出,那麼每層的複雜度nlogn,最多遞迴logn層,總複雜度nlogn 2 include in...

poj 1741 Tree 樹的分治

求樹上倆結點之間距離小於k的結點對個數 倆個點a,b的公共祖先為c,那麼這倆個點的距離就可以用dis a,c dis b,c 表示,我們可以不斷的處理這樣c,然後計算距離,處理點對,為了使平均效能最好,我們需要找的c為每一棵子樹的重心 需要注意的算點對的時候這種方法成立的條件是倆個點不在同一顆子樹上...