日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

算法实践--最小生成树(Kruskal算法)

發(fā)布時(shí)間:2023/12/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法实践--最小生成树(Kruskal算法) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是最小生成樹(Minimum Spanning Tree)

每?jī)蓚€(gè)端點(diǎn)之間的邊都有一個(gè)權(quán)重值,最小生成樹是這些邊的一個(gè)子集。這些邊可以將所有端點(diǎn)連到一起,且總的權(quán)重最小

下圖所示的例子,最小生成樹是{cf, fa, ab} 3條邊

?

Kruskal算法

用到上一篇中介紹的不相交集合(并查集)

首先,定義V是端點(diǎn)的集合,E是邊的集合,A為要求的最小生成樹集合

  • 初始A為空集合,每個(gè)端點(diǎn)都作為單獨(dú)的不相交集合
  • 將所有邊根據(jù)其權(quán)重進(jìn)行排序
  • 對(duì)每條邊(v1, v2),如果其兩個(gè)端點(diǎn)數(shù)據(jù)不同的不相交集,則將該邊加到集合A中,同時(shí)將v1和v2合并
  • 最終得到的A即為最小生成樹

?

生成過(guò)程的示例圖

?

C++代碼示例

?

struct Edge {char vertex1;char vertex2;int weight;Edge(char v1, char v2, int w):vertex1(v1), vertex2(v2), weight(w) {} };struct Graph {vector<char> vertice;vector<Edge> edges; };unordered_map<char, char> PARENT; unordered_map<char, int> RANK;char find(char vertex) {if (PARENT[vertex] == vertex) return PARENT[vertex];elsereturn find(PARENT[vertex]); }void MST(Graph& g) {vector<Edge> res;for (auto c : g.vertice) {PARENT[c] = c;RANK[c] = 0;}sort(g.edges.begin(), g.edges.end(), [](Edge x, Edge y) {return x.weight < y.weight;}); // O(E*log(E))for (Edge e : g.edges) { // O(E)char root1 = find(e.vertex1); // 最差O(E),因?yàn)橛杏涗浬疃?#xff0c;Find可以認(rèn)為很快char root2 = find(e.vertex2);if (root1 != root2) {res.push_back(e);if (RANK[root1] > RANK[root2]) {PARENT[root2] = root1;RANK[root1]++;} else {PARENT[root1] = root2;RANK[root2]++;}}}for (Edge e : res) {cout << e.vertex1 << " -- " << e.vertex2 << " " << e.weight << endl;} }void Union( char vertex_1, char vertex_2 ) { }int main() {char t[] = {'a', 'b', 'c', 'd', 'e', 'f'};Graph g;g.vertice = vector<char>(t, t + sizeof(t)/sizeof(t[0]));g.edges.push_back(Edge('a', 'b', 4)); // 稀疏圖用鏈來(lái)表示(E = O(V)) g.edges.push_back(Edge('a', 'f', 2)); // 如果是密集圖(E = O(V*V)), 用矩陣來(lái)表示g.edges.push_back(Edge('f', 'b', 5)); // 大部分感興趣的圖是稀疏的g.edges.push_back(Edge('c', 'b', 6));g.edges.push_back(Edge('c', 'f', 1));g.edges.push_back(Edge('f', 'e', 4));g.edges.push_back(Edge('d', 'e', 2));g.edges.push_back(Edge('d', 'c', 3));MST(g);return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/logchen/p/10274863.html

總結(jié)

以上是生活随笔為你收集整理的算法实践--最小生成树(Kruskal算法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。