隨著小hi擁有城市數目的增加,在之間所使用的prim演算法已經無法繼續使用了——但是幸運的是,經過計算機的分析,小hi已經篩選出了一些比較適合建造道路的路線,這個數量並沒有特別的大。
小ho聽到了這個問題,發表了感慨:「這不就是之前最短路問題的時候針對點集變大,但是邊集很小的稀疏圖麼?和spfa演算法當時遇到的問題很像誒!」
小hi嚴肅道:「是的!在現實生活中,大部分的圖其實都是稀疏圖,哪怕不是,也可以像我這種通過篩選的方式轉化為稀疏圖!所以稀疏圖上的問題是非常重要的!」
「是的!」小ho連連稱是,繼續道:「那難道這題也像spfa那樣子來做麼?但是最小生成樹似乎是不可以用寬度優先搜尋來解決的啊?」
「倒也沒有那麼複雜。」小hi道:「還記的我們在prim演算法中得出的結論——對於城市i(i≠1),如果i與城市1的距離不超過其他任何城市j(j≠1)與城市1的距離,那麼(1, i)這一條邊一定存在於某一棵最小生成樹中麼?」
「自然記得。」
「我們來把這個結論稍微改一下:圖中最短的邊一定屬於某棵最小生成樹。」小hi說道:「證明是簡單的——因為城市1的標號是隨意的,也就是無論給哪個城市標1都會有之前的結論,那麼對於任意節點來說它連線的所有邊中最短的邊一定存在於某一棵最小生成樹中,而整個圖中最短的一條邊一定是這樣的一條邊。」
小ho道:「是的,那麼也就是說我只需要不斷的找到當前圖中最短的一條邊(一開始就將所有的邊排序然後從小到大)——這樣的一條邊一定屬於某棵最小生成樹!然後我只需要將連線的2個節點合併成為乙個新的節點,那麼這個問題就變成了乙個規模-1的問題了!只需要不斷重複這樣的操作,就能夠使得問題最後變成1的規模,這個時候只需要之前找到的所有一定存在於最小生成樹中的邊的費用加起來就是答案了就可以了!」
小hi點了點頭,說道:「那麼還剩乙個問題,在prim問題中,由於合併都是和1號城市合併,所以只需要簡單的記錄乙個節點是否已經合併進了1號城市就可以了,但是在這裡卻會複雜很多,你有什麼想法麼?」
「你這就太小看我的記憶力了!」小ho抱怨道:「在當年遇到黑叔叔的時候,我們不是學會了一種並查集的方法麼?在這裡只需要用並查集維護哪些節點被合併到了一起,不就行了?」
「嗯~ o( ̄▽ ̄)o,算你聰明,趕緊去實現程式吧!」
輸入每個測試點(輸入檔案)有且僅有一組測試資料。
在一組測試資料中:
第1行為2個整數n、m,表示小hi擁有的城市數量和小hi篩選出路線的條數。
接下來的m行,每行描述一條路線,其中第i行為3個整數n1_i, n2_i, v_i,分別表示這條路線的兩個端點和在這條路線上建造道路的費用。
對於100%的資料,滿足n<=10^5, m<=10^6,於任意i滿足1<=n1_i, n2_i<=n, n1_i≠n2_i, 1<=v_i<=10^3.
對於100%的資料,滿足一定存在一種方案,使得任意兩座城市都可以互相到達。
輸出對於每組測試資料,輸出1個整數ans,表示為了使任意兩座城市都可以通過所建造的道路互相到達至少需要的建造費用。
sample input
5 29
1 2 674
2 3 249
3 4 672
4 5 933
1 2 788
3 4 147
2 4 504
3 4 38
1 3 65
3 5 6
1 5 865
1 3 590
1 4 682
2 4 227
2 4 636
1 4 312
1 3 143
2 5 158
2 3 516
3 5 102
1 5 605
1 4 99
4 5 224
2 4 198
3 5 894
1 5 845
3 4 7
2 4 14
1 4 185
sample output
92
#include
typedef
struct
tree;
tree a[
1000010
], t;
//定義結構體陣列用來儲存各個點之間的距離關係
int f[
100010
], sum=
0, count=0;
void
quick
(int left,
int right)
//快排
} t=a[left]
; a[left]
=a[i]
; a[i]
=t;quick
(left,i-1)
;quick
(i+1
,right)
;return;}
//並查集,查詢兩個點之間是否連通
intget
(int x)
}int
merge
(int x,
int y)
return0;
}int
main()
if(count==n-1)
//當所有邊都加入後
break;}
printf
("%d\n"
,sum)
;return0;
}
最小生成樹二 Kruscal演算法
還是直接看輸入輸出 輸入每個測試點 輸入檔案 有且僅有一組測試資料。在一組測試資料中 第1行為2個整數n m,表示小hi擁有的城市數量和小hi篩選出路線的條數。接下來的m行,每行描述一條路線,其中第i行為3個整數n1 i,n2 i,v i,分別表示這條路線的兩個端點和在這條路線上建造道路的費用。對於...
最小生成樹二 Kruscal演算法( )
描述 每個測試點 輸入檔案 有且僅有一組測試資料。在一組測試資料中 第1行為2個整數n m,表示小hi擁有的城市數量和小hi篩選出路線的條數。接下來的m行,每行描述一條路線,其中第i行為3個整數n1 i,n2 i,v i,分別表示這條路線的兩個端點和在這條路線上建造道路的費用。對於100 的資料,滿...
最小生成樹二Kruscal演算法
時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述隨著小hi擁有城市數目的增加,在之間所使用的prim演算法已經無法繼續使用了 但是幸運的是,經過計算機的分析,小hi已經篩選出了一些比較適合建造道路的路線,這個數量並沒有特別的大。所以問題變成了 小hi現在手上擁有n座城市...