AcWing 346. 走廊潑水節

題目鏈接:傳送門

構造一個完全圖就是每兩個點之間都有一條邊
要使最小生成樹不變那麼多加的邊只能相比原來的邊更大
在構造生成樹時如果兩個點集的大小分別爲siz[x],siz[y]siz[x],siz[y],那麼需要加的邊就是siz[x]siz[y]1siz[x]*siz[y]-1
需要加的邊權是這條樹邊的邊權+1+1,這樣才保證加的邊權最小
一邊構造生成樹一邊維護並查集的siz[]siz[]就好

#include <bits/stdc++.h>
#define A 1000010

using namespace std;
struct node {
	int a, b, w;
	friend bool operator < (const node a, const node b) {
		return a.w < b.w;
	}
}e[A];
int T, n, m, siz[A], fa[A];
int find(int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);}

int main(int argc, char const *argv[]) {
	cin >> T;
	while (T--) {
		scanf("%d", &n); int ans = 0;
		for (int i = 1; i <= n; i++) fa[i] = i, siz[i] = 1;
		for (int i = 1; i < n; i++) scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].w);
		sort(e + 1, e + n);
		for (int i = 1; i < n; i++) {
			int fx = find(e[i].a), fy = find(e[i].b);
			if (fx == fy) continue;
			ans += abs(siz[fx] * siz[fy] - 1) * (e[i].w + 1);
			fa[fy] = fx; siz[fx] += siz[fy];
		}
		cout << ans << endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章