最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++使用Kruskal和Prim算法實(shí)現(xiàn)最小生成樹

 更新時(shí)間:2020年04月26日 11:47:48   作者:瘋狂的指針  
這篇文章主要介紹了C++使用Kruskal和Prim算法實(shí)現(xiàn)最小生成樹,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

很久以前就學(xué)過最小生成樹之Kruskal和Prim算法,這兩個(gè)算法很容易理解,但實(shí)現(xiàn)起來并不那么容易。最近學(xué)習(xí)了并查集算法,得知并查集可以用于實(shí)現(xiàn)上述兩個(gè)算法后,我自己動(dòng)手實(shí)現(xiàn)了最小生成樹算法。

宏觀上講,Kruskal算法就是一個(gè)合并的過程,而Prim算法是一個(gè)吞并的過程,另外在Prim算法中還用到了一種數(shù)據(jù)結(jié)構(gòu)——優(yōu)先級隊(duì)列,用于動(dòng)態(tài)排序。由于這兩個(gè)算法很容易理解,在此不再贅述。接下來給出我的源代碼。

輸入

第一行包含兩個(gè)整數(shù)n和m,n表示圖中結(jié)點(diǎn)個(gè)數(shù),m表示圖中邊的條數(shù);接下來m行,每一行包含三個(gè)整數(shù)u,v,w,表示途中存在一條邊(u,v),并且其權(quán)重為w;為了便于調(diào)試,我的程序是從文件中輸入數(shù)據(jù)的;

輸出

輸出程序選擇的最小生成樹的權(quán)值之和以及每一條邊信息;

Kruskal算法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
 
struct Edge
{
 int u; //邊連接的一個(gè)頂點(diǎn)編號(hào)
 int v; //邊連接另一個(gè)頂點(diǎn)編號(hào)
 int w; //邊的權(quán)值
 friend bool operator<(const Edge& E1, const Edge& E2)
 {
 return E1.w < E2.w;
 }
};
//創(chuàng)建并查集
void MakeSet(vector<int>& uset, int n)
{
 uset.assign(n, 0);
 for (int i = 0; i < n; i++)
 uset[i] = i;
}
//查找當(dāng)前元素所在集合的代表元
int FindSet(vector<int>& uset, int u)
{
 int i = u;
 while (uset[i] != i) i = uset[i];
 return i;
}
void Kruskal(const vector<Edge>& edges, int n)
{
 vector<int> uset;
 vector<Edge> SpanTree;
 int Cost = 0, e1, e2;
 MakeSet(uset, n);
 for (int i = 0; i < edges.size(); i++) //按權(quán)值從小到大的順序取邊
 {
 e1 = FindSet(uset, edges[i].u);
 e2 = FindSet(uset, edges[i].v);
 if (e1 != e2) //若當(dāng)前邊連接的兩個(gè)結(jié)點(diǎn)在不同集合中,選取該邊并合并這兩個(gè)集合
 {
 SpanTree.push_back(edges[i]);
 Cost += edges[i].w;
 uset[e1] = e2; //合并當(dāng)前邊連接的兩個(gè)頂點(diǎn)所在集合
 }
 }
 cout << "Result:\n";
 cout << "Cost: " << Cost << endl;
 cout << "Edges:\n";
 for (int j = 0; j < SpanTree.size(); j++)
 cout << SpanTree[j].u << " " << SpanTree[j].v << " " << SpanTree[j].w << endl;
 cout << endl;
}
int main()
{
 ifstream in("data.txt");
 
 int n, m;
 in >> n >> m;
 vector<Edge> edges;
 edges.assign(m, Edge());
 for (int i = 0; i < m; i++)
 in >> edges[i].u >> edges[i].v >> edges[i].w;
 sort(edges.begin(), edges.end()); //排序之后,可以以邊權(quán)值從小到大的順序選取邊
 Kruskal(edges, n);
 
 in.close();
 
 system("pause");
 return 0;
}

Prim算法:

#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <queue>
using namespace std;
struct Node
{
 int v;
 int w;
 Node(int a, int b) :v(a), w(b){}
};
struct Edge
{
 int u;
 int v;
 int w;
 Edge(int a, int b, int c) :u(a), v(b), w(c){}
 friend bool operator<(const Edge& E1, const Edge& E2)
 {
 return E1.w>E2.w;
 }
};
int n, m;
vector<list<Node>> Adj;
priority_queue<Edge> Q;
 
int FindSet(vector<int>& uset, int v)
{
 int i = v;
 while (i != uset[i]) i = uset[i];
 return i;
}
 
void Prim()
{
 int Cost = 0; //用于統(tǒng)計(jì)最小生成樹的權(quán)值之和
 vector<Edge> SpanTree; //用于保存最小生成樹的邊
 vector<int> uset(n,0); //用數(shù)組來實(shí)現(xiàn)并查集
 Edge E(0, 0, 0);
 for (int i = 0; i < n; i++) uset[i] = i; //并查集初始化
 for (auto it = Adj[0].begin(); it != Adj[0].end(); it++) 
 Q.push(Edge(0, it->v, it->w)); //根據(jù)Prim算法,開始時(shí)選取結(jié)點(diǎn)0,并將結(jié)點(diǎn)0與剩余部分的邊保存在優(yōu)先隊(duì)列中
 //循環(huán)中每次選取優(yōu)先隊(duì)列中權(quán)值最小的邊,并更新優(yōu)先隊(duì)列
 while (!Q.empty())
 {
 E = Q.top();
 Q.pop();
 if (0 != FindSet(uset, E.v))
 {
 Cost += E.w;
 SpanTree.push_back(E);
 uset[E.v] = E.u;
 for (auto it = Adj[E.v].begin(); it != Adj[E.v].end(); it++)
 if (0 != FindSet(uset, it->v)) Q.push(Edge(E.v, it->v, it->w));
 }
 }
 cout << "Result:\n";
 cout << "Cost: " << Cost << endl;
 cout << "Edges:\n";
 for (int j = 0; j < SpanTree.size(); j++)
 cout << SpanTree[j].u << " " << SpanTree[j].v << " " << SpanTree[j].w << endl;
 cout << endl;
}
int main()
{
 ifstream in("data.txt");
 
 int u, v, w;
 in >> n >> m;
 Adj.assign(n, list<Node>());
 for (int i = 0; i < m; i++)
 {
 in >> u >> v >> w;
 Adj[u].push_back(Node(v,w));
 Adj[v].push_back(Node(u,w));
 }
 Prim();
 
 in.close();
 
 system("pause");
 return 0;
}

就實(shí)現(xiàn)而言,Kruskal算法比Prim算法更容易,代碼更易于理解。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺析C++ 數(shù)據(jù)類型

    淺析C++ 數(shù)據(jù)類型

    這篇文章主要介紹了C++ 數(shù)據(jù)類型的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-08-08
  • C++將模板實(shí)現(xiàn)放入頭文件原理解析

    C++將模板實(shí)現(xiàn)放入頭文件原理解析

    這篇文章主要為大家介紹了C++將模板實(shí)現(xiàn)放入頭文件原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • C語言string庫strcpy、strcmp、strcat函數(shù)的使用

    C語言string庫strcpy、strcmp、strcat函數(shù)的使用

    這篇文章主要介紹了C語言string庫strcpy、strcmp、strcat函數(shù)的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • c++ qsort 與sort 對結(jié)構(gòu)體排序?qū)嵗a

    c++ qsort 與sort 對結(jié)構(gòu)體排序?qū)嵗a

    這篇文章主要介紹了c++ qsort 與sort 對結(jié)構(gòu)體排序?qū)嵗a,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-11-11
  • C++類中三大函數(shù)詳解(構(gòu)造、析構(gòu)和拷貝)

    C++類中三大函數(shù)詳解(構(gòu)造、析構(gòu)和拷貝)

    c++三大函數(shù)指的是拷貝構(gòu)造、拷貝賦值、析構(gòu)函數(shù),下面這篇文章主要給大家介紹了關(guān)于C++類中三大函數(shù)(構(gòu)造、析構(gòu)和拷貝)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • STL容器之vector源碼詳細(xì)解讀

    STL容器之vector源碼詳細(xì)解讀

    這篇文章主要介紹了STL容器之vector源碼詳細(xì)解讀,vector的數(shù)據(jù)安排和array和類似,它們的主要差別在于空間的運(yùn)用和靈活性,array是靜態(tài)空間,一旦配置了就不能改變,需要的朋友可以參考下
    2024-01-01
  • C++ cmake實(shí)現(xiàn)日志類的示例代碼

    C++ cmake實(shí)現(xiàn)日志類的示例代碼

    CMake是一個(gè)跨平臺(tái)的安裝(編譯)工具,可以用簡單的語句來描述所有平臺(tái)的安裝(編譯過程)。本文就來利用cmake實(shí)現(xiàn)日志類,感興趣的小伙伴可以了解一下
    2023-03-03
  • C語言實(shí)現(xiàn)掃雷OvO(完整代碼)

    C語言實(shí)現(xiàn)掃雷OvO(完整代碼)

    相信大家都玩過掃雷游戲,因?yàn)樗?jīng)典了,今天我們用C語言來模擬實(shí)現(xiàn)掃雷游戲,結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2022-04-04
  • C語言實(shí)現(xiàn)電話簿管理系統(tǒng)

    C語言實(shí)現(xiàn)電話簿管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電話簿管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C/C++運(yùn)用WMI接口實(shí)現(xiàn)查詢系統(tǒng)信息

    C/C++運(yùn)用WMI接口實(shí)現(xiàn)查詢系統(tǒng)信息

    Windows?Management?Instrumentation(WMI)是一種用于管理和監(jiān)視Windows操作系統(tǒng)的框架,本文主要介紹了如何運(yùn)用WMI接口實(shí)現(xiàn)查詢系統(tǒng)信息,感興趣的可以了解下
    2023-11-11

最新評論

静安区| 文水县| 和龙市| 松潘县| 句容市| 黔南| 定安县| 阜阳市| 昭觉县| 高邮市| 江门市| 高陵县| 金寨县| 钟祥市| 宜宾县| 阜康市| 无极县| 辽阳县| 临沂市| 广宁县| 丹棱县| 石台县| 思茅市| 高台县| 大方县| 汉川市| 台东县| 阆中市| 中江县| 石首市| 常州市| 元江| 永胜县| 晋城| 攀枝花市| 中卫市| 汕头市| 仙居县| 松桃| 砚山县| 美姑县|