講真,去年學理論的時候就覺得普里姆演算法與迪傑斯特拉太像了,乙個是最小生成樹,乙個是最短路徑,但用的思路都是在餘下的當中找與當前現有的距離最短的。
與迪傑斯特拉偽**不同之處在於:
:將g[u][v]賦值給v與集合s的最短距離d[v];,也就是說,這裡的d[v]表示頂點v與集合最短的距離。而在迪傑斯特拉演算法中,d陣列表示的是某個頂點到原點的最短路徑距離。
偽**:
//g為圖,一般設成全域性變數;陣列d為頂點與集合s的最短距離
prim (g,d)
}}}
鄰接矩陣版:
const
int maxn =
1000
;const
int inf =
1000000000
;int n,g[maxn]
[maxn]
;int d[maxn]
;bool vis[maxn]=;
intprim()
}if(u ==-1
)return-1
; vis[u]
=true
; ans +
= d[u]
;//將與集合s距離最小的邊加入最小生成樹
for(
int v =
0;v }return ans;
//返回最小生成樹的邊權之和
}
鄰接表版:
const
int maxn =
1000
;const
int inf =
1000000000
;struct node
;vectoradj[maxn]
;int n;
int d[maxn]
;//頂點與集合s的最短距離
bool vis[maxn]=;
intprim()
}if(u ==-1
)return-1
; vis[u]
=true
; ans +
= d[u]
;//將與集合s距離最小的邊加入最小生成樹
for(
int j =
0;j .size()
;j++)}
}return ans;
}
亞歷山卓攻打惡魔大陸的案例:
《演算法筆記》p407
#include
#include
using
namespace std;
const
int maxn =
1000
;const
int inf =
1000000000
;int n,m,g[maxn]
[maxn]
;int d[maxn]
;bool vis[maxn]=;
intprim()
}if(u ==-1
)return-1
; vis[u]
=true
; ans +
= d[u]
;for
(int v =
0;v }return ans;
}int
main()
int ans =
prim()
;printf
("%d\n"
,ans)
;//連線圖上所有頂點,經過的邊權最短路徑和
return0;
}/*6 10
0 1 4
0 4 1
0 5 2
1 2 6
1 5 3
2 3 6
2 5 5
3 4 4
3 5 5
4 5 3
*/
最小生成樹 Prim演算法的實現及應用
關於prim演算法 先把有的點放於乙個集合 或者陣列 裡,這個集合裡存放的是所有走過的點。初始值為0或者false表示還沒有點 宣告乙個一維陣列用於記錄各點的權值 可理解為起始點到目標點的距離 宣告乙個二維陣列用於記錄某點到某一點的權值,如果這兩點不可達到,則設定為無窮大 具體執行過程 先從某一點開...
最小生成樹 Prim演算法的實現及應用
關於prim演算法 先把有的點放於乙個集合 或者陣列 裡,這個集合裡存放的是所有走過的點。初始值為0或者false表示還沒有點 宣告乙個一維陣列用於記錄各點的權值 可理解為起始點到目標點的距離 宣告乙個二維陣列用於記錄某點到某一點的權值,如果這兩點不可達到,則設定為無窮大 具體執行過程 先從某一點開...
最小生成樹 Prim演算法的實現及應用
關於prim演算法 先把有的點放於乙個集合 或者陣列 裡,這個集合裡存放的是所有走過的點。初始值為0或者false表示還沒有點 宣告乙個一維陣列用於記錄各點的權值 可理解為起始點到目標點的距離 宣告乙個二維陣列用於記錄某點到某一點的權值,如果這兩點不可達到,則設定為無窮大 具體執行過程 先從某一點開...