普利姆算法(Prim Algorithm)
最小生成树的概念
所谓最小生成树,就是在一个具有N个顶点的带权连通图G中,如果存在某个子图G',其包含了图G中的所有顶点和一部分边,且不形成回路,并且子图G'的各边权值之和最小,
则称G'为图G的最小生成树。
普利姆算法(Prim Algorithm)
算法描述:
普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠密网的最小生成树,时间复杂度为O(n*n)。
算法过程:
1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分是未处理的结点(B集合)。
2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找出A中顶点关联的边权值最小的那个(设为v),将此顶点从B中删除,加入集合A中。
3.递归重复步骤2,直到B集合中的结点为空,结束此过程。
4.A集合中的结点就是由Prime算法得到的最小生成树的结点,依照步骤2的结点连接这些顶点,得到的就是这个图的最小生成树。
#define INF 0x3f3f3f3f//无穷大
#define MAX 1000
int map[MAX][MAX], lowcost[MAX];
bool visit[MAX];//bool为布尔型用作逻辑判断
int nodenum, sum;
void prim(){
int temp, k;
sum = 0;
memset(visit, false, sizeof(visit)); //初始化visit
visit[1] = true;
for(int i = 1; i <= nodenum; ++i) //初始化lowcost[i]
lowcost[i] = map[1][i];
for(int i = 1; i <= nodenum; ++i)//找生成树集合点集相连最小权值的边
{
temp = INF;
for(int j = 1; j <= nodenum; ++j)
if(!visit[j] && temp > lowcost[j])
temp = lowcost[k = j];
if(temp == INF) break;
visit[k] = true; //加入最小生成树集合
sum += temp;//记录权值之和
for(int j = 1; j <= nodenum; ++j) //更新lowcost数组
if(!visit[j] && lowcost[j] > map[k][j])
lowcost[j] = map[k][j];
}
}