函式對應關係寫錯, 調了兩個小時, 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 後來想通了,真的是對於每顆子樹都把其所有結點單獨提取出來,而且這麼做就是...