基本prim最小生成树
1·任意定点构树————标记数组标记入树
2·初始化更新维护dis数组
3·选出dis中最近的点j加入树中,并以j为起点松弛
4.重复第3步选出n-1个点
堆优化prim最小生成树 准备:dis数组,p优先队列,vis数组记录每个定点在最小堆中的位置
1.初始化优先队列,以定义的起点为起点的所有的边入队
2.弹出一条边,判断vis,如果边的终点访问了换边,直至没有访问过
3.以这条边的指向点为起点,根据vis数组选择性入队
4.重复指行n-1次,得出最小生成树————PS每一次执行都会得出一条边
看下面详细代码
#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <queue> #define inf (1 << 30) using namespace std; const int maxn = 110; const int maxm = 5e5 + 50; int dis[110]; struct node{ int to,cost,pre; friend bool operator < (node a,node b) { return a.cost > b.cost; } }e[maxm]; int id[maxn],cnt; int vis[maxn]; priority_queue<node> q; void init(int n) { memset(id,-1,sizeof(id)); memset(vis,0,sizeof(vis)); cnt = 0; for(int i = 0;i <= n;i++) dis[i] = inf; while(q.size())q.pop(); } void add(int from,int to,int cost) { e[cnt].to = to; e[cnt].cost = cost; e[cnt].pre = id[from]; id[from] = cnt++; } int queue_prim(int s,int n) { int res = 0; vis[s] = 1; for(int i = id[s];~i;i = e[i].pre) q.push(e[i]); for(int i = 1;i < n;i++) { if(q.size() == 0)break; node now = q.top(); q.pop(); if(vis[now.to] == 1) { while(vis[now.to]) { now = q.top(); q.pop(); } } res += now.cost; vis[now.to] = 1; for(int j = id[now.to];~j;j = e[j].pre) { if(!vis[e[j].to])q.push(e[j]); } } return res; } int main() { int n; while(~scanf("%d",&n),n) { int a,b,x; init(n); for(int i = 1;i <= n * (n - 1) / 2;i++){ scanf("%d%d%d",&a,&b,&x); add(a,b,x); add(b,a,x); } printf("%d\n",queue_prim(1,n)); } return 0; }