題目
計算樹上任兩點最短路徑的最大權重之和。
解法
樹代表沒有環,每個邊至少是一組點對最短路徑的最大權重。
由小到大枚舉邊,計算有多少點對被這個邊隔開,再乘上權重。
範例:
1
2
3
4
5
|
o o
\ w /
o ─ o
/ \
o o
|
答案加上 $$3\times 3\times w$$
這可以用並查集做到。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
int parent[100001];
int findParent(int x) {
return x == parent[x] ? x : parent[x] = findParent(parent[x]);
}
struct Edge {
int u, v, w;
bool operator<(Edge e) {
return w < e.w;
}
} edges[100000];
ll n_member[100001];
void solve() {
int n;
cin >> n;
for(int i = 1; i < n; i++) {
cin >> edges[i].u >> edges[i].v >> edges[i].w;
}
sort(edges + 1, edges + n);
iota(parent + 1, parent + n + 1, 1);
fill_n(n_member + 1, n, 1);
ll result = 0;
for(int i = 1, x, y; i < n; i++) {
x = findParent(edges[i].u);
y = findParent(edges[i].v);
result += n_member[x] * n_member[y] * edges[i].w;
parent[y] = x;
n_member[x] += n_member[y];
}
cout << result;
}
|
Author
93wilsonlu
LastMod
2021-08-15
License
原創文章,如需轉載請註明文章作者和出處。謝謝!