【图论】最小生成树——prim算法

 一、什么是最小生成树

最小生成树(Minimum Spanning Tree,MST)

在一个给定的无向图G中求一棵树T

  • 树T拥有图G的所有顶点
  • 所有边都来自图G
  • 使得整棵树的边权最小

【图论】最小生成树——prim算法_第1张图片

 【图论】最小生成树——prim算法_第2张图片

贪心策略:

prim算法:    让小树长大

kruskal算法:将森林合并成树

二、prim算法 

 与Dijkstra算法区别:

思想几乎完全相同,

Dijkstra算法的最短距离指到源点s的最短距离;

prim算法的最短距离指到集合s的最短距离

 【图论】最小生成树——prim算法_第3张图片

时间复杂度是O(V^2),

邻接表实现通过堆优化可使时间复杂度降为O(VlogV+E) 

尽量在稠密图上使用

三、程序示例

//邻接矩阵版
//求边权之和ans
#include 
#define MAXN 510
#define MAXDATA 1000000000
using namespace std;

int G[MAXN][MAXN];
int nv,ne,c1;//顶点数,边数,起始点

int ans;//最小生成树的边权之和
int dis[MAXN];
int collected[MAXN];
void prim(){
    fill(dis,dis+nv,MAXDATA);
    dis[c1]=0;
    for(int i=0;iG[minId][j]){
                    //不需要经过minId了,只需要到minId最短
                    dis[j]=G[minId][j];
                }
            }
        }
    }

}

int main(){
    scanf("%d %d %d",&nv,&ne,&c1);//顶点数,边数,起始点

    for(int i=0;i
//邻接表版
#include 
#include 
#define MAXN 510
#define MAXDATA 1000000000
using namespace std;

struct Node
{
    int v;
    int dis;
    Node(int _v,int _dis):v(_v),dis(_dis){}
};


vector Adj[MAXN];//邻接表
int nv,ne,c1;//顶点数,边数,起始点

int ans;//最小生成树的边权之和
int dis[MAXN];
int collected[MAXN];
void prim(){
    fill(dis,dis+nv,MAXDATA);
    dis[c1]=0;
    for(int i=0;idist){//未收录且需要更新
                dis[v]=dist;
            }
        }
    }

}

int main(){
    scanf("%d %d %d",&nv,&ne,&c1);//顶点数,边数,起始点

    int tmp1,tmp2,tmpl;
    for(int i=0;i

测试数据(起始点为0):

6 10 0
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

输出结果:15 

你可能感兴趣的:(图论,数据结构,算法)