洛谷 P2126 Mzc家中的男家丁

2022-05-06 22:39:07 字數 2252 閱讀 7797

從題目不難看出這是一道最小生成樹的裸題,然後再看資料範圍:

$n <= 2300 $

\(m <= 400000\)

首先想到kruskal或者prim都可以滿足需要,但考慮到這兩種演算法中kruskal應用更廣,所以今天我們重點講一下kruskal演算法

首先回歸最小生成樹的定義:給定一張邊帶權的無向圖\(g = (v, e)\),\(n=|v|\),由\(v\)中\(n\)個節點和\(e\)中\(n-1\)條邊構成的無向連通圖稱為\(g\)的一棵生成樹。邊的權值之和最小的生成樹被稱為最小生成樹。

進入今天的正題:kruskal演算法

kruskal演算法是基於一種貪心的思想,他總是維護無向圖的最小生成森林。最初,生成森林是由零條邊構成,每個節點構成一棵僅包含乙個節點的樹。

kruskal演算法的主體步驟,就是不斷從剩餘的邊中選出一條權值最小,且他的兩個端點在生成森林中分屬於兩棵不同的樹,將這條邊加入生成森林中。

那麼,我們自然就會想到圖的連通性應該如何維護呢? 為了**效率和簡便,我們一般都採用並查集來維護。(事實上,kruskal演算法的巨大優越性也是在加入並查集優化後才得以體現的,而我們平時所說的kruskal一般都是帶並查集優化的。)

演算法流程:

1.建立並查集,每個點構成乙個集合。

2.將各邊按權值從小到大排序,依次掃瞄每條邊。

3.若一條邊兩端點在同一集合中,則忽略這條邊直接跳過。

4.否則,合併他們所在的集合,將權值之和累加到答案中。

5.第四步中選中的邊就構成了這張圖的最小生成樹。

一圖勝千言:

這是一幅無向圖:

將各邊按權值從小到大排完序後應為:

x      y       val

1 2 2

1 3 2

1 4 3

3 4 3

2 3 4

然後我們開始執行kruskal的主體流程:

列舉第一條邊(1, 2, 2),將其加入生成森林中,生成森林變為:

列舉第二條邊(1, 3, 2),將其加入生成森林中,生成森林變為:

列舉第三條邊(3,4,3),將其加入生成森林中,生成森林變為:

你會發現,此時我們已經選出\(n - 1\)條邊,那麼這就是這張圖的最小生成樹,將權值累加起來即為答案,kruskal演算法結束。

ps:這幅圖比較簡單,但是重在理解kruskal的流程。

原理理解之後,**就會變得異常簡單了,注意,重點在於一定要理解,廢話不多說,直接上**:

#include #include #include #include #define maxn 400005

using namespace std;

int n, m, fa[maxn], tot, head[maxn], sum;

struct edgeedge[maxn];

bool cmp(edge x,edge y) //自定義比較函式

int find(int x)

bool judge(int x,int y)

void merge(int x,int y)

//優雅的三行並查集

int main()

sort(edge+1, edge+m+1, cmp); //權值從大到小排序

for(int i = 1; i <= n; i++) fa[i] = i;

for(int i = 1; i <= m; i++)

} //當然,這部分也可以封裝到函式中,看個人喜好

cout << sum << '\n';

return 0;

}

最後,本篇題解旨在幫助那些剛剛接觸到最小生成樹的oier們更好的理解,若有任何問題,請私信本人。

洛谷 P2126 Mzc家中的男家丁

題目背景 與 的 還沒有眾人皆知,所以我們要來宣傳一下。家很有錢 開玩笑 他家有 個男家丁,現在 要將她們全都聚集起來 幹什麼就不知道了 現在知道 與男家丁們互相之間通訊的時間,請算出把他們每個人叫到需要的總時間 要重複的哦 保證能把他們每個人叫到。輸入格式 第一行有乙個數n,表示有n個男家丁。第二...

洛谷 P2126 Mzc家中的男家丁

與 的 還沒有眾人皆知,所以我們要來宣傳一下。家很有錢 開玩笑 他家有 個男家丁,現在 要將她們全都聚集起來 幹什麼就不知道了 現在知道 與男家丁們互相之間通訊的時間,請算出把他們每個人叫到需要的總時間 要重複的哦 保證能把他們每個人叫到。輸入格式 第一行有乙個數n,表示有n個男家丁。第二行乙個數m...

洛谷 2126 Mzc家中的男家丁

mzc與djn的 還沒有眾人皆知,所以我們要來宣傳一下。mzc家很有錢 開玩笑 他家有 個男家丁,現在mzc要將她們全都聚集起來 幹什麼就不知道了 現在知道mzc與男家丁們互相之間通訊的時間,請算出把他們每個人叫到需要的總時間 要重複的哦 保證能把他們每個人叫到。第一行有乙個數n,表示有n個男家丁。...