求樹上每兩點的距離之和
阿新 • • 發佈:2018-11-05
給定一棵n個節點的樹和n-1條邊的權值,求每兩點間的權值的總和。\((n \leq 1e5)\)
暴力做法
求出每兩個點的\(lca (O(nlogn)\)預處理,\(O(logn)\)查詢),預處理路徑字首和後\(O(1)\)求得
\(n^2\)數量級的點對,時間複雜度\(O(n^2logn)\),TLE了。正解:統計每條邊被經過的次數,乘以權值,求和
1.每條邊連線了兩個聯通塊\(a b\),一個有\(k\)個點,一個有\(n-k\)個點。
2.因為要求的是任意兩點的距離和,故每條邊在\(a\)中的每一個點與\(b\)中的每一個點的路徑上出現,即出現了\(k*(n-k)\)
3.做一遍預處理,對每個節點求出子樹大小,即可在\(O(n)\)的時間內求出每兩點的權值總和
主要程式碼:
int siz[maxn]; void dfs(int u, int fa) { siz[u] = 1; ou[u] = ou[fa] ^ 1; for (auto v:G[u]) { if (v != fa) { dfs(v, u); siz[u] += siz[v]; } } } for (int i = 1; i <= n; ++i) ans += 1ll * siz[i] * (n - siz[i]) * w[i];