例如:要在n個城市之間鋪設光纜,主要目標是要使這 n 個城市的任意兩個之間都可以通訊,但鋪設光纜的費用很高,且各個城市之間鋪設光纜的費用不同,因此另乙個目標是要使鋪設光纜的總費用最低。這就需要找到帶權的最小生成樹。
好下面我們就直接貼**:在**中有注釋能直接更快的明白最小生成樹該怎麼寫!
**一:prim(普里姆)演算法
/*
prim演算法是乙個不高效,並且占用記憶體較為高的一種最小生成樹演算法。但是好理解。這樣呢也確實一種方法。
畢竟學習演算法就是學習思想嘛!
*/#include
#include
#include
using
namespace
std;
int n,m,mann[100][100],vis[100],dis[100];
//mann中儲存節點之間的距離,預設是最大值mx
//vis陣列是標記節點是否已經被加入的了最小生成樹裡邊
//dis是記錄最小生成樹到各個未加入最小生成樹節點的距離
const
int mx=1
<<29;//上限,這個程式的最大值
int pri()
memset(vis,0,sizeof(vis));//初始化vis,表示都未加入最小生成樹
vis[1]=1;//表示節點1加入最小生成樹。
int minn,to,sum=0;
for(int i=1;ifor(int j=1;j<=n;j++)
}sum+=minn;//總代價+當前算出的小代價
vis[to]=1;//表示當前找到最小節點加入最小生成樹
for(0
int j=1;j<=n;j++)}}
return sum;
}int main()
}int f,t,v;//表示f節點到t節點的代價為v
for(int i=1;i<=m;i++)
printf("%d\n",pri());
}return
0;}
介紹完prim(普里姆)演算法就該介紹 kruskal(克魯斯卡爾)演算法了 ,kruskal演算法涉及到了並查集的知識但是 如果並查集學得好 看一眼就會知道原理了。
**二:kruskal(克魯斯卡爾)演算法
/*
這個演算法比起prim演算法是比較節省空間的。並且感覺時間上也是很節省的。因為是先排序再查詢。
*/#include
#include
#include
using
namespace
std;
int n,m,record[100];
//n,m n代表節點的總數,m代表在節點間共有多少種代價。
//record代表各個節點到 「祖」 的距離,學過並查集都知道這個東西
struct nodearray[100];
int cmp(node a,node b)
return record[x];
}int solve()
if(cnt==n-1)
}return -1;
}int main()
for(int i=1;i<=m;i++)
sort(array+1,array+m+1,cmp);//對各個節點 代價 進行排序。按照從小到大
printf("\n%d\n",solve());
}return
0;}
最後: prim演算法和kruskal演算法都能從連通圖找出最小生成樹。區別在於prim演算法是挨個找,而kruskal是先排序再找。是不是感覺最小生成樹很簡單呢???當然如果你想要把 prim演算法和kruskal演算法合併的話可以嘗試用鍊錶這個資料結構儲存節點–>排序–>像kruskal演算法那樣生成最小生成樹!!
心靈雞湯:
既然選擇程式,就要匠心所致;
既然選擇遠方,就要風雨兼程
最小生成樹模板
prim演算法理解可以參考部落格 prim演算法模板 int prime int v int i,j,sum 0,min,k sum是權重和 for i 1 i n i lowcost i 表明當前狀態下在u內距離v點 s中各點 距離的最小值,每個u中點s 中點 都計算 lowcost i map ...
最小生成樹 模板
const int maxn 1010 const int maxm 200020 struct edge edges maxm int father maxn int find int x int cmp edge a,edge b 將邊按權值排序 int kruskal int n,int m ...
模板 最小生成樹
題目描述 如題,給出乙個無向圖,求出最小生成樹,如果該圖不連通,則輸出orz 輸入輸出格式 輸入格式 第一行包含兩個整數n m,表示該圖共有n個結點和m條無向邊。n 5000,m 200000 接下來m行每行包含三個整數xi yi zi,表示有一條長度為zi的無向邊連線結點xi yi 輸出格式 輸出...