problem description
省**「暢通工程」的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。經過調查評估,得到的統計表中列出了有可能建設公路的若干條道路的成本。現請你編寫程式,計算出全省暢通需要的最低成本。
input
測試輸入包含若干測試用例。每個測試用例的第1行給出評估的道路條數 n、村莊數目m ( < 100 );隨後的 n
行對應村莊間道路的成本,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間道路的成本(也是正整數)。為簡單起見,村莊從1到m編號。當n為0時,全部輸入結束,相應的結果不要輸出。
output
對每個測試用例,在1行裡輸出全省暢通需要的最低成本。若統計資料不足以保證暢通,則輸出「?」。
sample input
3 31 2 1
1 3 2
2 3 4
1 32 3 2
0 100
sample output3?
【題目分析】
典型的最小生成樹問題,我是習慣用kruscal演算法,另外還有prim演算法,不過從時間上來說kruscal更加優化。
【演算法思想】
kruscal演算法的基本思想:首先把每條邊按照權值從小到大排序,然後按照排序後的順序逐一考察每條邊,看將這條邊加進來是否會形成環,不會則加入到最小生成樹的集合中來,否則跳過,重複這個步驟直到將最後兩個不連通的點連通,結束。所得的樹一定是最小生成樹,因為排序(滿足的最小這個條件),因為不成環(滿足了樹這個條件)。
【演算法實現】
1.首先定義乙個結構體,包括x,y,c(代表x地到y地的花費為c);
2.輸入資料;
3.對輸入的資料按照c進行結構體排序;
4.考察:這兒用到乙個find函式和parents陣列,用來判斷是否會形成迴路,如果不形成迴路就將其權值加進來並改變parents陣列的值,否則只須改變parents陣列的值然後跳過;
5.所有邊迴圈完了以後,輸出最小花費。
source code:
#include#includeview code#include
#include
#include
#define max 1010
using
namespace
std;
int parents[110
];typedef
struct
node
node;
node edges[
6000
];bool
cmp(node x,node y)
int find(int
x)int kruskal(int
m) }
return
mincost;
}int
main()
if(count>1) puts("?"
);
else printf("
%d\n
",mincost);
}return0;
}
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
最小生成樹
package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...
最小生成樹
define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...