解題觀念 Disjoint Set - MST 可以參考我的課程簡報:MST & Shortest Path
Disjoint Set 關於 Disjoint Set 的基本觀念可以參考我的這篇文章:Algorithm - Disjoint Set
Minimum Spanning Tree Kruskal’s Algorithm 關於 Minimum Spanning Tree Kruskal’s Algorithm 的基本觀念可以參考我的這篇文章:Algorithm - Minimum Spanning Tree Kruskal’s Algorithm
題目敘述 電腦線路連接
今天給你一些電腦線路連接的狀態,以及原來選取的網路線 現在基於此基礎上加入了 K 條捷徑線路,而原有的全部可用線路有 M 條 請幫忙連接線路,使電腦彼此接連通且線路長度和最小
每組輸入中 第一行為數字 n,代表有多少電腦
接下來 n-1 行表示目前連接狀態的線路 有三個數 u、v、w 表示線段兩端連接的電腦及線路長度
再來給予數字 K,代表新給予的線路 接下來 K 行有三個數 u、v、w 表示新線段兩端連接的電腦及線路長度
最後給予數字 M,代表所有可用線路 接下來 M 行有三個數 u、v、w 表示原線段兩端連接的電腦及線路長度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 5 1 2 5 1 3 5 1 4 5 1 5 5 1 2 3 2 6 1 2 5 1 3 5 1 4 5 1 5 5 3 4 8 4 5 8
Output 每組輸出中 第一行輸出原連接狀態的線路長度 第二行輸出考慮新線路後的最短線路連接長度
Solution Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 #include <bits/stdc++.h> using namespace std;const int maxn = 1000000 +5 ;struct Edge { int u; int v; int w; bool operator < (const Edge &rhs) const { return w < rhs.w; } }; int N, M;int total = 0 ; int parent[maxn];vector<Edge> edge; int find (int x) { if (parent[x] < 0 ) return x; return parent[x] = find (parent[x]); } void Union (int a, int b) { a = find (a); b = find (b); if (a != b){ if (parent[a] < parent[b]){ parent[a] += parent[b]; parent[b] = a; } else { parent[b] += parent[a]; parent[a] = b; } } } void kruskal () { memset (parent, -1 , sizeof (parent)); sort (edge.begin (), edge.end ()); int i, j; total = 0 ; for (i = 0 , j = 0 ; i < N-1 && j < M; ++i){ while (find (edge[j].u) == find (edge[j].v)) ++j; Union (edge[j].u, edge[j].v); total += edge[j].w; ++j; } } int main () { bool space = false ; while (cin >> N){ if (space) cout << endl; space = true ; int u, v, w; total = 0 ; for (int i = 0 ; i < N-1 ; ++i){ cin >> u >> v >> w; total += w; } cout << total << endl; int K; cin >> K; for (int i = 0 ; i < K; ++i){ cin >> u >> v >> w; edge.push_back ({u, v, w}); } cin >> M; for (int i = 0 ; i < M; ++i){ cin >> u >> v >> w; edge.push_back ({u, v, w}); } M = K + M; kruskal (); cout << total << endl; while (!edge.empty ()) edge.pop_back (); } }