POJ 1741 TREE 點分治 樹上問題

2021-07-29 05:10:46 字數 1242 閱讀 2801

函式對應關係寫錯, 調了兩個小時, fukk。

大致思路:點分支。

找以每乙個節點(其實不是每乙個)為根節點的重心, 用dis[ ]表示經過重心的每一條鏈的長度。但是計算的時候會計算到以重心為根節點的子樹中的dis[ ],所以對於與重心子樹中的每乙個節點v,都應該去重新計算它的路徑長度到重心的路徑長度,然後用ans減去這裡面的合法方案數。因為是分治,分而治之。所以計算完乙個重心的就應該去刪除(vis[g] = true)。

所用到的陣列siz[i] (存i的樹大小「包括它本身」), mx[i] (最大子樹的大小),vis[i] (刪除重心)。用乙個dfs()找子樹大小,與mx (預處理),再用另乙個dfs()找重心。

#include "cctype"

#include "cstdio"

#include "cstring"

#include "algorithm"

#define max(a, b) ((a) > (b) ? (a) : (b))

template

inline

bool readin(t &x)

template

inline

void write( t x )

template

inline

bool writein(t x)

write(x);

return

true;

}const

int maxn = (int) 1e4 + 5;

int mx[maxn], head[maxn], siz[maxn], dis[maxn], n, k, u, v, l, ne, ans, g, gsiz, cnt;

bool vis[maxn];

struct edge

} g[maxn << 1];

inline

bool adde(int u, int v, int w)

void dfsiz(int u, int f)

}}void dfs_g(int root, int u, int f)

}void dfsdis(int u, int f, int w)

}inline

int cal(int u, int w)

return rt;

}void dfs(int u)

}}int main()

}

POJ 1741 Tree 樹的分治 點分治

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

poj 1741 tree 樹的點分治

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

POJ1741 Tree(樹的點分治)

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