道路公升級(最小生成樹KRUSKAL)

2021-08-30 19:25:00 字數 1726 閱讀 4504

z國有 n 個城市和 m 條雙向道路,每條道路連線了兩個不同的城市,保證所有城市之間都可以通過這些道路互達。每條道路都有乙個載重量限制,這限制了通過這條道路的貨車最大的載重量。道路的編號從 1 至 m 。巧合的是,所有道路的載重量限制恰好都與其編號相同

現在,要挑選出若干條道路,將它們公升級成高速公路,並滿足如下要求:

在上面的前提下,要求選出的道路數目盡可能少。

求需要挑選出哪些道路公升級成高速公路(如果有多種方案請任意輸出一種)。

第一行 2 個用空格隔開的整數 n,m ,分別表示城市數目、道路數目。

第 2 行到第 m+1 行,每行 2 個用空格隔開的整數 u,v 描述一條從 u 到 v 的雙向道路,第 i+1 行的道路的編號為 i 。

注意:資料只保證不存在連線的城市相同的道路(自環),並不保證不存在兩條完全相同的邊(重邊)

第一行乙個整數 k ,表示公升級成高速公路的道路數。

接下來 k 行每行乙個整數,從小到大輸出所有選出的道路的編號。

3 3

1 22 3

1 3

2

23

對於 20% 的資料,保證 n≤5,m≤10。

對於 60% 的資料,保證 n≤1,000,m≤5,000。

對於 100% 的資料,保證 n≤200,000,m≤400,000。

時間限制:10 sec

空間限制:256 mb

[提示1:真的可能有多種方案嗎?]

[提示2:k 是否一定為 n-1 呢?(也就是說,選出的道路是否恰好構成了一棵樹?)]

[提示3:這道題和最小生成樹有什麼關係呢?]

#include using namespace std;

const int n = 500005;

//並查集

class unionset

//查詢節點x所在集合的根(路徑壓縮)

//x:節點x

//返回值:根

int find(int x)

//將x節點與y節點所在集合合併

//x:乙個節點

//y:乙個節點

//返回值:返回true表示成功合併,返回false表示已經在乙個集合裡了

bool merge(int x,int y)

return false;

}}us;

// 給定乙個n個點m條邊的無向圖,第i條邊邊權為i,求所有需要公升級的邊

// n:n個點

// m:m條邊

// u:大小為m的陣列,表示m條邊的其中乙個端點

// v:大小為m的陣列,表示m條邊的另乙個端點

// 返回值:所有需要公升級的邊,從小到大排列;第一小問的答案自然即為返回值的size,所以你不必考慮如何返回size

vectorgetanswer(int n, int m, vectoru, vectorv)

int main()

vectorans = getanswer(n, m, u, v);

printf("%d\n", int(ans.size()));

for (int i = 0; i < int(ans.size()); ++i)

printf("%d\n", ans[i]);

return 0;

}

道路鋪設(最小生成樹)

題目描述 隨著如今社會的不斷變化,交通問題也變得越來越重要,所以市長決定建設一些公路來方便各個城市之間的 和交易。雖然市長的想法很好,但是他也遇到了一般人也經常頭疼的問題,那就是手頭的經費有限 在規劃過程中,設計師們已經預算出部分城市之間建設公路的經費需求。現在市長想知道,它能不能將他的m個城市在有...

soj 3366 複習最小生成樹kruskal

題目大意 要建井,每個地方都要有,可以選擇直接在這裡挖井,也可以選擇從其他地方已經有井的地方建一條路到這個地方來。有一段時間沒有寫過最小生成樹了,感覺都有一點快要忘記了的感覺。這道題之前沒有過,借鑑了一下別人的思想。發現真的好簡單。而且這種方法在以前使用過,這回居然沒有想出來,要反思一下了。感覺跟之...

最小生成樹演算法 Prim演算法和Kruskal演算法

prim演算法理解,可以看這篇文章 其實就是每次從當前樹中外選取乙個離樹最近且不構成環的點,同時sum記錄權值,然後把這個點加入樹中,直到所有節點都被訪問過,最小生成樹生成成功,輸出最小生成樹的權值和。下面是prim演算法的板子,和最短路有點相似,也稱為 加點法 最小生成樹prim演算法 inclu...