關於圖的最小生成路徑——Kruskal演算法和Prime演算法
關於圖的最小生成路徑——Kruskal演算法和Prime演算法
寫部落格其實就是為了回顧所學的~現在學起這些東西都更輕鬆了…
/**
Kruskal演算法:關鍵三步——1、排序;2、判斷迴圈條件;3、找符合要求的邊;
關鍵:用到了並查集;
**/
#include<iostream>
using namespace std ;
const int Max_Size = 100 ;
const int INFINITY = 65535 ;
int n,e;
typedef struct ENode{
int v1,v2 ;
int w ;
}ENode;
ENode E[Max_Size];
int Father[Max_Size];
void Create(){//建圖
cin >> n >> e ;
for(int i = 0 ;i<e;i++){
cin >> E[i].v1 >> E[i].v2 >> E[i].w;
}
}
bool cmp(ENode &a,ENode &b){
return a.w < b.w;
}
int Find_Father(int x ){//並查集(其實就是找到各個節點的根節點,然後壓縮路徑)
int a = x ;
while (x != Father[x]){//回溯找到根節點
x = Father[x] ;
}
while (a != Father[a]){//壓縮路徑
int z = a ;
a = Father[a];
Father[z] = x ;
}
return x ;
}
int sum = 0 ;
int Kruskal(){
int num = 0 ;//迴圈次數(跳出迴圈的條件二:邊數 = 節點數-1——樹的性質)
for(int i = 0 ;i<n ; i++ ){//初始化,將各節點的根節點置為自身
Father[i] = i ;
}
sort(E,E+e,cmp);
for(int i = 0 ;i<e ;i++){//對邊操作,所以小於邊數
int fa_v1 = Find_Father(E[i].v1);
int fa_v2 = Find_Father(E[i].v2);
if(fa_v1 != fa_v2){//在不同的連通塊(根節點不一樣)
Father[fa_v1] = fa_v2; //加入並查集
sum += E[i].w; //權值累加
num ++ ;
if(num == n -1){
break ;
}
}
}
if(num != n-1){//不等於,則代表圖不連通,此時樹肯定也不連通
return -1 ;
}
return sum ;
}
int main (){
Create();
cout<<"最小路徑為:" << Kruskal() << endl ;
return 0 ;
}
下面是關於Prime演算法(個人覺得可以跟Dijkstra一起學)
/**
prime演算法與Dijkstra差不多,唯一不同的就是
prime演算法是最小路徑,計算過程是集合與新的節點來比較距離;
而Dijkstra是點與點來比較距離;
**/
#include<iostream>
using namespace std ;
const int Max_Size = 100 ;
const int INFINITY = 65535 ;
int n,e;
int Visited[Max_Size];
int Dis[Max_Size]; //新節點與集合的距離
int G[Max_Size][Max_Size];
void Create(){
cin >> n >> e ;
for(int i = 0 ;i<n ;i++ ){//初始化圖
for(int j = 0 ;j< n ;j++ ){
if(i == j){
G[i][j] = 0 ;
}else {
G[i][j] = INFINITY;
}
}
}
for(int i = 0;i<e;i++){
int v1,v2,w;//邊的兩個端點,權值
cin >> v1 >> v2 >> w ;
G[v1][v2] = w ;
G[v2][v1] = w ;
}
}
int sum = 0 ;
int Prime(){
fill(Dis, Dis+Max_Size, INFINITY);//用fill不用memset的原因,後者賦值大數會出問題
memset(Visited, 0, sizeof(Visited));
Dis[0] = 0 ;//規定起始節點(無所謂哪個)
for(int i =0 ;i< n ;i++){//對節點操作,所以是小於n
int u = -1 ,min = INFINITY ;
for(int j = 0 ;j< n;j++ ){//同Dijkstra,找最短
if(Visited[j] == 0 && Dis[j] < min ){
u = j ;
min = Dis[j];
}
}
if(u == -1 ) {
sum = -1 ;
return -1;
}
Visited[u] = 1 ;
sum += Dis[u];//相當於將u加入到集合了
for(int j = 0 ;j< n ;j++ ){
if(Visited[j] == 0 && G[u][j] < Dis[j]){//這裡判斷條件,跟Dijkstra也不一樣,這兒是點到集合的距離
Dis[j] = G[u][j];
}
}
}
return sum ;
}
int main (){
Create();
cout<<"最小路徑為:" << Prime() << endl ;
return 0 ;
}
如有問題,歡迎大家指正~
相關文章
- 最小生成樹:Kruskal演算法和Prim演算法演算法
- 最小生成樹-Prim演算法和Kruskal演算法演算法
- Kruskal 最小生成樹演算法演算法
- 最小生成樹之Prim演算法和Kruskal演算法演算法
- 最小生成樹(MinSpanTree)的Kruskal演算法演算法
- 演算法學習之路|最小生成樹——prime演算法演算法
- 最小生成樹---普里姆演算法(Prim演算法)和克魯斯卡爾演算法(Kruskal演算法)演算法
- 東哥帶你刷圖論第五期:Kruskal 最小生成樹演算法圖論演算法
- 最小生成樹,Prim演算法與Kruskal演算法,408方向,思路與實現分析演算法
- Matlab生成Kruskal最小生成樹Matlab
- 演算法-圖論-最小生成樹演算法圖論
- 北極通訊網路——最小生成樹kruskal
- 圖論中的最小生成樹演算法圖論演算法
- 最小生成樹——Prim演算法和Kruscal演算法演算法
- 最小樹形圖(有向圖的最小生成樹)朱劉演算法演算法
- 圖解Prim&Kruskal演算法圖解演算法
- 【JAVA演算法】圖論演算法 --求最小生成樹Prim演算法Java演算法圖論
- Kruskal演算法演算法
- 最小生成樹的演算法演算法
- 最小生成樹__Kurskal演算法演算法
- 最小生成樹__Prim演算法演算法
- 演算法題:三角形的最小路徑和演算法
- 最小生成樹之 Prim 演算法演算法
- 【演算法學習】最小生成樹演算法
- vue 關於圖片路徑的問題Vue
- 分享一種最小 Perfect Hash 生成演算法演算法
- 演算法與資料結構之帶權圖與圖最小生成樹演算法資料結構
- 演算法——路徑問題演算法
- 關於尋路演算法的一些思考(7):地圖表示演算法地圖
- 最小生成樹prim普里姆演算法演算法
- 最小生成樹之普里姆演算法演算法
- Boruvka求最小生成樹(菠蘿演算法)演算法
- 基於路徑的實體圖關係抽取模型模型
- 路徑查詢演算法應用之A*演算法演算法
- 最小樹形圖(朱劉演算法)演算法
- 關於尋路演算法的一些思考(6):預先計算好的路徑的所用空間演算法
- 路徑規劃: 淺談路徑規劃演算法演算法
- 資料結構和演算法學習筆記八:帶權連通圖的最小生成樹資料結構演算法筆記