Prim算法:每次找距离集合V'的最近的点 + 松弛操作( dis[j] = min(dis[j] , map[k][j]) )
prim的松弛操作和迪杰斯特拉的松弛操作不一样,不要混淆了!
Vector + 优先队列实现
#include#include <string.h> #include #include #include #define MAX 50005 #define INF 0x3f3f3f3f using namespace std; typedef struct Node{ int v; //边的终点 int w; //权值 }Node; struct cmp{ //重载比较运算符,用于优先队列的排序 bool operator()(Node a,Node b){ return a.w>b.w; } }; vector map[MAX]; priority_queue , cmp >q; //用优先队列优化 int vis[MAX]; //是否被访问过 int dis[MAX]; //该集合到所有点的最短距离 int n,m; void prim(){ memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; max_dis; int min_,k; Node node1; //加入第一个结点 node1.v=1; node1.w=0; q.push(node1); while(!q.empty()){ Node node=q.top(); //每次取优先队列的队头 q.pop(); int v=node.v; int w=node.w; vis[v]=1; for(int j=0;j
Vector实现
#include#include <string.h> #include #include #define MAX 50005 #define INF 0x3f3f3f3f using namespace std; typedef struct Node{ int v; int w; }Node; vector map[MAX]; int vis[MAX]; //是否被访问过 int dis[MAX]; //该集合到所有点的最短距离 int n,m; void prim(){ memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; int min_,k; for(int i=1;i<=n;i++){ //依次加入每一个顶点 min_=INF; k=-1; for(int j=1;j<=n;j++){ if(!vis[j] && dis[j] //找当前不在集合V'内且与集合V'最近的一个点 min_=dis[j]; k=j; } } if(k==-1) return ; //图不连通 vis[k]=1; for(int j=0;j
二维数组实现 (50000 *50000 用不了二维数组)
#include#include <string.h> #include #define MAX 1000 #define INF 0x3f3f3f3f using namespace std; int map[MAX][MAX]; int vis[MAX]; //是否被访问过 int dis[MAX]; //该集合到所有点的最短距离 int n,m; void prim(){ memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; int min_,k; for(int i=1;i<=n;i++){ //依次加入每一个顶点 min_=INF; k=-1; for(int j=1;j<=n;j++){ if(!vis[j] && dis[j] //找当前不在集合V'内且与集合V'最近的一个点 min_=dis[j]; k=j; } } if(k==-1) return ; //图不连通 vis[k]=1;for(int j=1;j<=n;j++){ //更新与k点相邻的点v到集合V'的最短距离 if(!vis[j]){ if(dis[j]>map[k][j]){ //点v没有被访问过且点v到点k的距离小于点v到集合V'的距离 dis[j]=map[k][j]; } } } } }