C++ 图论-Prim最小生成树

来源:互联网 发布:手机apk反编译软件 编辑:程序博客网 时间:2024/06/01 12:37

Prim算法求最小生成树,思想类似Dijkstra最短路径算法,可以用于稠密图。

Kruskal算法是每次加边,Prim是每次加一个点,并且始终是树.



【过程】

1 从任意顶点开始构造生成树。用标记记录哪些顶点已经加入生成树.

2 用dis数组存储生成树到每个顶点的距离

3 在dis中找最小值,就是离生成树最近的顶点。再用这个点更新dis(松弛)

4 重复3,直到包含n个点.



(一)一般的算法

#include <iostream>using namespace std;const int MAX = 1e7;int n, m;int G[5001][5001];   //邻接矩阵存图bool flag[5001];     //标记是否在生成树中int dis[5001];       //生成树到顶点到距离int cnt;             //生成树中的顶点个数int sum;             //最小生成树费用void Prim() {/*从第一个顶点开始*/for(int i=1; i<=n; i++) dis[i] = G[1][i];flag[1] = true;cnt ++;while(cnt < n) {int min = MAX;int k;            //记录最小距离的顶点编号for(int i=1; i<=n; i++)if(!flag[i] && dis[i] < min) {min = dis[i];k = i;}flag[k] = true;   //把最小距离的那个顶点加入生成树cnt ++;sum += dis[k];for(int i=1; i<=n; i++)if(!flag[i] && dis[i] > G[k][i])dis[i] = G[k][i]; //更新}cout << sum << endl;}int main() {int u, v, w;cin >> n >> m;for(int i=1; i<=n; i++)for(int j=1; j<=n; j++)G[i][j] = ((i==j)?0:MAX);for(int i=1; i<=m; i++) {cin >> u >> v >> w;G[u][v] = G[v][u] = min(G[u][v], w);}Prim();return 0;}


(二)堆优化