poj 1741 Tree(樹的點分治)

2022-05-06 16:18:16 字數 1031 閱讀 3187

給出乙個n個結點的樹和乙個整數k,問有多少個距離不超過k的點對。

首先對於乙個樹中的點對,要麼經過根結點,要麼不經過。所以我們可以把經過根節點的符合點對統計出來。接著對於每乙個子樹再次運算。如果不用點分治的技巧,時間複雜度可能退化成\(o(n^2)\)(鏈)。如果對於子樹重新選根,找到樹的重心,就一定可以保證時間複雜度在\(o(nlogn)\)內。

具體技巧是:首先選出樹的重心,將重心視為根。接著計算出每個結點的深度,以此統計答案。由於子樹中可能出現重複情況,需要在子樹中相應的減去一部分ans。具體實現在**中。

#include #include #include using namespace std;

const int maxn=1e4+5;

struct graph

}edge[maxn*2];

int cntedge, fir[maxn];

void addedge(int x, int y, int v)

edge& getlink(int x)

void reset()

}g;int n, k, size[maxn], w[maxn], dep[maxn];

int cnt[maxn], tail;

bool done[maxn];

//獲取子樹大小

int getsize(int now, int par, int num)

++size[now]; w[now]=max(w[now], num-size[now]);

return size[now];

}//獲取根的位置

int getroot(int now, int par)

return ans;

}int solve(int now, int num)

return ans;

}int main()

printf("%d\n", solve(1, n));

}return 0;

}

poj 1741 tree 樹的點分治

很經典的點分治入門題 參考 其實還是有很多種姿態來搞,各個題解也都很清楚,差不多也就是那麼個意思,所以只是來總結一下需要注意和難以理解的東西 1.為什麼每次要找重心?給定的樹並不確定,所以樹的深度直接影響時間複雜度 因為你每一次都需要去找經過這乙個節點且兩點之間距離 k的,即是 i,j d i d ...

POJ1741 Tree(樹的點分治)

題目給一棵邊帶權的樹,統計路徑長度 k的點對數。樓教主男人八題之一,分治演算法在樹上的應用。一開始看 看不懂,以為重心和距離那些是一遍預處理得來的。感覺上不敢想每棵子樹都求一遍重心和距離 那樣時間複雜度怎麼會只有o nlogn 後來想通了,真的是對於每顆子樹都把其所有結點單獨提取出來,而且這麼做就是...

POJ 1741 Tree 樹的分治 點分治

題目大意 給出一顆無根樹和每條邊的權值,求出樹上兩個點之間距離 k的點的對數。思路 樹的點分治。利用遞迴和求樹的重心來解決這類問題。因為滿足題意的點對一共只有兩種 1.在以該節點的子樹中且不經過該節點。2.路徑經過該節點。對於第一種點,我們遞迴處理 第二種點,我們可以將所有子樹的節點到這個子樹的根節...