基本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;
}