【問題描述】
2023年,全中國實現了戶戶通電。作為一名電力建設者,小明正在幫助一帶一路上的國家通電。
這一次,小明要幫助 n 個村莊通電,其中 1 號村莊正好可以建立乙個發電站,所發的電足夠所有村莊使用。
現在,這 n 個村莊之間都沒有電線相連,小明主要要做的是架設電線連線這些村莊,使得所有村莊都直接或間接的與發電站相通。
小明測量了所有村莊的位置(座標)和高度,如果要連線兩個村莊,小明需要花費兩個村莊之間的座標距離加上高度差的平方,形式化描述為座標為 (x_1, y_1) 高度為 h_1 的村莊與座標為 (x_2, y_2) 高度為 h_2 的村莊之間連線的費用為
sqrt((x_1-x_2)(x_1-x_2)+(y_1-y_2)(y_1-y_2))+(h_1-h_2)*(h_1-h_2)。
在上式中 sqrt 表示取括號內的平方根。請注意括號的位置,高度的計算方式與橫縱座標的計算方式不同。
由於經費有限,請幫助小明計算他至少要花費多少費用才能使這 n 個村莊都通電。
【輸入格式】
輸入的第一行包含乙個整數 n ,表示村莊的數量。
接下來 n 行,每個三個整數 x, y, h,分別表示乙個村莊的橫、縱座標和高度,其中第乙個村莊可以建立發電站。
【輸出格式】
輸出一行,包含乙個實數,四捨五入保留 2 位小數,表示答案。
【樣例輸入】
41 1 3
9 9 7
8 8 6
4 5 4
【樣例輸出】
17.41
【評測用例規模與約定】
對於 30% 的評測用例,1 <= n <= 10;
對於 60% 的評測用例,1 <= n <= 100;
對於所有評測用例,1 <= n <= 1000,0 <= x, y, h <= 10000。
解析可以說是最小生成樹的裸題了——連通==樹,代價最小==最小生成
用kruskal演算法一氣呵成。
不過要進行一些處理:
每個村莊看做是乙個頂點,編號儲存
兩兩組成邊,用費用做邊的權重
做好資料處理,然後就是排序,從小到大把邊新增到最小生成樹的邊集(也不用真正新增,符合的邊把代價累加就行,不符合的邊忽略)
符合與不符合,當然要用並查集了。
#include
#include
#include
#include
using namespace std;
struct edge //定義邊集元素
;//返回頂點x的根節點,p為並查集陣列
intfind
(vector<
int>
& p,
int x)
bool compare
(edge a,edge b)
//邊權值比較函式
//kruskal演算法生成最小生成樹,返回其權值和
double
kruskal
(int n,
int m,vector
& e)
//n:頂點的個數,m:邊的數目,e:邊集
sort
(e.begin()
,e.end()
,compare)
;//按邊的權值從小到大進行排序
for(
int i=
0;i)//遍歷所有的邊
if(num_edge==n-1)
//最小生成樹的邊數等於n-1,滿足這一條件結束
break;}
if(num_edge//邊的數目小於n-1說明不連通
return-1
;return ans;
}struct point
;vector cun;
intmain()
);}for
(int i=
0;i1;i++
)//兩兩之間相連,建立邊集);
cnt++;}
}double res =
kruskal
(n,cnt,e)
;printf
("%.2lf"
,res)
;return0;
}
Prim演算法 Kruskal演算法
一 prim演算法 1 要求 1 生成一顆連通的樹 2 生成樹 包含全部頂點,v 1條邊,沒有迴路,並且新增一條邊會變成有迴路 3 權重和最小 2 過程模擬 最重要 貪心的思想,每一步都要選擇權值最小的,這棵樹所有跟頂點相連的邊中最小的。從根節點開始,讓樹慢慢的長大。過程 從v1開始 跟v1有聯絡的...
Prim演算法 Kruskal演算法
prim演算法 kruskal演算法 prim演算法和kruskal演算法,都是用來找出圖中最小生成樹的演算法,兩個演算法有些小差別。prim演算法 又稱普里姆演算法,以圖上的頂點為出發點,逐次選擇到最小生成樹頂點集距離最短的頂點為最小生成樹的頂點,並加入到該頂點集,直到包含所有的頂點。1.選擇一出...
Kruskal演算法 Prim演算法
最小生成樹是什麼?自a2392008643的部落格 此演算法可以稱為 加邊法 初始最小生成樹邊數為0,每迭代一次就選擇一條滿足條件的最小代價邊,加入到最小生成樹的邊集合裡。把圖中的所有邊按代價從小到大排序 把圖中的n個頂點看成獨立的n棵樹組成的森林 按權值從小到 擇邊,所選的邊連線的兩個頂點ui,v...