CH6201 走廊潑水節 最小生成樹

2022-04-30 21:42:28 字數 1493 閱讀 1236

描述

【簡化版題意】給定一棵n個節點的樹,要求增加若干條邊,把這棵樹擴充為完全圖,並滿足圖的唯一最小生成樹仍然是這棵樹。求增加的邊的權值總和最小是多少。

我們一共有n個oier打算參加這個潑水節,同時很湊巧的是正好有n個水龍頭(至於為什麼,我不解釋)。n個水龍頭之間正好有n-1條小道,並且每個水龍頭都可以經過小道到達其他水龍頭(這是一棵樹,你應該懂的..)。但是oier門為了迎接中中的挑戰,決定修建一些個道路(至於怎麼修,秘密~),使得每個水龍頭到每個水龍頭之間都有一條直接的道路連線(也就是構成乙個完全圖唄~)。但是oier門很懶得,並且記性也不好,他們只會去走那n-1條小道,並且希望所有水龍頭之間修建的道路,都要大於兩個水龍頭之前連線的所有小道(小道當然要是最短的了)。所以神cow們,幫那些oier們計算一下吧,修建的那些道路總長度最短是多少,畢竟修建道路是要破費的~~

輸入格式

本題為多組資料~

第一行t,表示有t組測試資料

對於每組資料

第一行n,表示水龍頭的個數(當然也是oier的個數);

2到n行,每行三個整數x,y,z;表示水龍頭x和水龍頭y有一條長度為z的小道

輸出格式

對於每組資料,輸出乙個整數,表示修建的所有道路總長度的最短值。

樣例輸入

2

31 2 2

1 3 3

41 2 3

2 3 4

3 4 5

樣例輸出
4

17

資料範圍與約定

樣例解釋

第一組資料,在2和3之間修建一條長度為4的道路,是這棵樹變成乙個完全圖,且原來的樹依然是這個圖的唯一最小生成樹.

我們可以按照一種類似kruskal的思路來做。把邊權排個序依次加入並查集。

思路是這樣,每次往並查集中加入一條邊時,除非是第一條加入的邊,那麼勢必會產生一張沒有聯通完全的圖。按照題意,我們最後得出的是一張完全圖,所以說每次加入邊的時候我們就可以把沒連上的點連上了,反正他們最後勢必要連,不如連更小邊權的邊。我們用sx和sy表示某兩個不交叉的並查集的元素個數,這時我們假設現在要在兩個並查集之間連一條當前的最小邊z,假設它的邊權為val,其它沒有連線的節點如果連線起來,而且我們想讓它們的邊權最小,就會產生sx*sy-1個點相連的情況,以及多出(val+1)*(sx*sy-1)的邊權。

這就是增加的邊權了,而且它勢必最小。

#include#include

#include

#include

#include

#include

#define n 10010

using

namespace

std;

ints[n],fa[n];

struct

nodeg[n];

bool

operator

<(node a,node b)

intget(int

x)int

main()

cout

}return0;

}

CH 6201走廊潑水節

描述 簡化版題意 給定一棵n個節點的樹,要求增加若干條邊,把這棵樹擴充為完全圖,並滿足圖的唯一最小生成樹仍然是這棵樹。求增加的邊的權值總和最小是多少。我們一共有n個oier打算參加這個潑水節,同時很湊巧的是正好有n個水龍頭 至於為什麼,我不解釋 n個水龍頭之間正好有n 1條小道,並且每個水龍頭都可以...

CH6201 走廊潑水節

題目大意 給定一棵樹,要求增加若干條邊,將其轉化為完全圖,且該完全圖以該樹為唯一的最小生成樹,求增加的邊權最小是多少。題解 完全圖的問題一般要考慮組合計數。重新跑一遍克魯斯卡爾演算法,每次並查集在合併時進行計數,因為要求最小生成樹唯一,必須保證每條邊都比當前連線兩個聯通塊的邊要至少大 1,因此每次合...

走廊潑水節 最小生成樹 思維

給定乙個樹,你需要在這個樹中新增若干條邊,使得這顆樹變成乙個完全圖,並且滿足圖的唯一最小生成樹仍是這個樹,問你最小新增的邊權為多少?不妨我們從頭開始構造這個最小生成樹。假設我們當前加入的邊為edge u,v,cost 如果u所在的並查集為s u v為s v 因為我們加的這條邊,很明顯是當前最小的 k...