走廊潑水節 最小生成樹定理

2022-02-15 23:28:32 字數 1587 閱讀 7990

給定一棵n個節點的樹,要求增加若干條邊,把這棵樹擴充為完全圖,並滿足圖的唯一最小生成樹仍然是這棵樹。

求增加的邊的權值總和最小是多少。

注意: 樹中的所有邊權均為整數,且新加的所有邊權也必須為整數。

第一行包含整數t,表示共有t組測試資料。

對於每組測試資料,第一行包含整數n。

接下來n-1行,每行三個整數x,y,z,表示x節點與y節點之間存在一條邊,長度為z。

每組資料輸出乙個整數,表示權值總和最小值。

每個結果佔一行。

1≤n≤6000

1≤z≤100

2

31 2 2

1 3 3

41 2 3

2 3 4

3 4 5

4

17

這道題考的是最小生成樹定理

定理

任意一顆最小生成樹一定包含無向圖中權值最小的邊

證明(反證法)

假設g = (v, e)存在一顆最小生成樹不包含權值最小邊(x, y, z),

將(x, y, z)加入圖中,則出現環, 最小生成樹, 不能有環,

所以要從這個環中刪去一條邊(當然能樹還是聯通的),

這個環中任一條邊都比(x, y, z)大, 故肯定留下這條邊, 故這顆生成樹不是最小生成樹

推論⭐

給定一張無向圖g(v,e), n = |v|, m = |e|, 從e中選k< n - 1條邊構成g的森林

若在從m = k條邊中選(n - 1 - k)構成g的生成樹,並且邊權值最小,

則給生成樹必定包含 m - k條邊中連線最小生成樹的邊來連線森林的兩棵樹

故這道題就是不斷選鏈結森林且是最小生成樹的邊

所以存在森林, 然後用體中的一條邊(x, y, z)將 x節點 和 y節點 所在的樹鏈結

因為要生成完全圖,則著兩棵樹中的所有節點新增邊權都要為 z + 1

不然如果小於等於z, 這條新新增的邊鏈結了x和y所在的樹, 且邊權值最小, 則必定為最小生成樹的邊(和題意矛盾)

所以就是一邊連邊, 一邊新增 z + 1邊

實現細節見**

#include #define rep(i,a,b) for(int i=a;i<=b;++i)

using namespace std;

typedef long long ll;

const int maxn = 6005;

struct rec e[maxn];

bool operator <(rec& a, rec& b)

int _, n, fa[maxn], s[maxn];

int find(int x)

void unit(int x, int y)

int main ()

cout << ans << '\n';

}return 0;

}

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

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

最小生成樹拓展 走廊潑水節

給定一棵n個節點的樹,要求增加若干條邊,把這棵樹擴充為完全圖,並滿足圖的唯一最小生成樹仍然是這棵樹。求增加的邊的權值總和最小是多少。注意 樹中的所有邊權均為整數,且新加的所有邊權也必須為整數。輸入格式 第一行包含整數t,表示共有t組測試資料。對於每組測試資料,第一行包含整數n。接下來n 1行,每行三...

CH6201 走廊潑水節 最小生成樹

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