最小生成树---prim算法
基本思想:
任选一个节点为头节点,然后找出离”整个树‘距离最小的节点,纳入树内,直到所有节点都纳入树内。
数据结构:
数组,邻接矩阵储存图
算法思想:基于贪心算法:即每一步都选择当前最优路径。
关键:离“整个树”最小: 利用dis[]数组储存
来看代码:
for(k=1;k<=n;k++)//更新dis[]数组,更新刚加入的j节点,使得非集合R的点的dis值为其到集合R点的最小值
{
if(book[k]==0&&dis[k]>e[j][k])
dis[k]=e[j][k];
}
}
由于代码中有详细注释,这里不再赘述:
来看代码:
#include<stdio.h>
#include<string.h>
#include<conio.h>
int main()
{
int n,m,i,j,k,min,t1,t2,t3;
int e[40][40],dis[40],book[40]={0};
int inf=9999;
int count=0,sum=0;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)//初始化邻接矩阵
for(j=1;j<=n;j++)
if(i==j) e[i][j]=0;
else e[i][j]=inf;
for(i=1;i<=m;i++)//无向图,录入边
{
scanf("%d %d %d",&t1,&t2,&t3);
e[t1][t2]=t3;
e[t2][t1]=t3;
}
for(i=1;i<=n;i++)//初始化数据
dis[i]=e[1][i];
book[1]=1;//初始化
count++;//已经有一个节点进入集合R
while(count<n)//当n个节点都进入集合R,则退出循环
{
min=inf;//初始化min的值
for(i=1;i<=n;i++)
{
if(book[i]==0&&dis[i]<min)
{
min=dis[i];
j=i;
}
} //找出与已经进入集合R的点所有的非集合R点的最近的点j
book[j]=1;//j节点入集合R
count++;
sum+=dis[j];//sum加上
for(k=1;k<=n;k++)//更新dis[]数组,更新刚加入的j节点,使得非集合R的点的dis值为其到集合R点的最小值
{
if(book[k]==0&&dis[k]>e[j][k])
dis[k]=e[j][k];
}
}
printf("%d",sum);
getch();
return 0;
}
sum代表着所生成的数的最短路径的权重和。
下一篇还要介绍Kruskal的最短路径算法
到时候会分析两者关系