Andrew是某個公司的系統管理員,他計劃爲他的公司搭建一個新的網絡。在新的網絡中,有N個集線器,在集線器之間可以通過網線連接。由於公司職員需要通過集線器訪問整個網絡,因此每個集線器必須能通過網線連接其它集線器(可以有中轉集線器)。由於有不同的長度可選,且網線越短越便宜,因此Andrew設計的方案必須確保最長的單根網線的長度在所有方案中最小。試幫助Andrew設計一個網絡,滿足上述條件~
輸入描述:輸入文件中包含多個測試數據。每個測試數據的第1行爲兩個整數:N和M,N表示網絡中集線器的數目,2<=N<=1000,集線器的編號從1~N;M表示集線器之間的連接數
目,1<=M<=15000。接下來M行描述了M對連接的信息,每對連接的格式爲:所連接的兩個集線器的編號,連接這兩個集線器所需的網線的長度,且長度爲不超過1000000的正整數。兩個集線器之間最多有一對連接:每個集線器都不能與自己連接。測試數據保證網絡是連通的。測試數據一直到文件尾。輸出描述:對輸入文件中的每個測試數據,首先輸出連接方案中最長的單根網線的長度(這個值取到最小);然後輸出設計方案:先輸出一個整數P,代表所使用的網線數目;然後輸出P對頂點,表示每根網線所連接的集線器編號,整數之間用空格或換行符隔開。樣例輸入:5 81 2 51 4 21 5 12 3 62 4 33 4 53 5 44 5 6樣例輸出:441 51 42 43 5解:本題和實例一種的思路差不多,不過要注意輸出的要求——先輸出最長的單根網線的長度,再輸出選出的邊,所以要再附加一個數組ans來存儲選出的邊的信息~代碼+註釋:#include<stdio.h> #include<stdlib.h> #define MAXN 1001 //頂點個數最大值 #define MAXM 150001 //邊的個數最大值 typedef struct edge { int u, v, w; //起點、終點、權值 }edge; edge edges[MAXM]; //鄰接矩陣 int parent[MAXN]; //頂點i所在集合的根結點 int N, M; //頂點數和邊數 int ans[MAXM], ai; //存儲選出的邊 int i, j; //循環變量 int num; //記錄選出的邊的個數 int maxedge; //最長邊 void UFset() //將parent初始化 { for(i = 1; i <= N; i++) parent[i] = -1; } int Find(int x) //找到頂點x所在集合的根結點 { int s, tmp; for(s = x; parent[s] >= 0; s = parent[s]) ; while(s != x) { tmp = parent[x]; parent[x] = s; x = tmp; } return s; } void Union(int R1, int R2) //合並不在同一集合的兩點 { int r1 = Find(R1), r2 = Find(R2); int tmp = parent[r1] + parent[r2]; if(parent[r1] > parent[r2]) { parent[r1] = r2; parent[r2] = tmp; } else { parent[r2] = r1; parent[r1] = tmp; } } void Kruskal() { UFset(); for(i = 0; i < M; i++) { if(Find(edges[i].u) != Find(edges[i].v)) { ans[ai] = i; ai++; //記錄選中的邊 if(edges[i].w > maxedge) maxedge = edges[i].w; num++; //記錄選中的邊的個數 Union(edges[i].u, edges[i].v); } if(num >= N-1) break; } } int cmp(const void *a, const void *b) { return (*(const edge *)a).w-(*(const edge *)b).w; } int main() { while(scanf("%d%d", &N, &M) != EOF) { for(i = 0; i < M; i++) scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w); qsort(edges, M, sizeof(edges[0]), cmp); maxedge = 0; num = 0; ai = 0; Kruskal(); printf("%d\n", maxedge); printf("%d\n", num); for(i = 0; i < ai; i++) printf("%d %d\n", edges[ans[i]].u, edges[ans[i]].v); } return 0; }
運行結果: