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...