废话
本篇博客只是单纯的作为自己复习的记录。
正篇
图论中两个最小生成树算法之一prim。思想比较简单,关键在于自己有没有认真细致的观察它。
思想:把图的顶点U分为两个集合,V是已生成最小树集(V初始化:选择一个顶点作为起始点),U - V是待选择集。重复下面操作:v∈V,u∈(U - V)的边中找一条代价最小的边,将u加入V中,直到V = U为止。
**准备:**设置一个数组short Edge【maxn】作为候选最短边集,数组元素包括adjvex,lowcost分别表示最短边的邻接点和权值。
模拟:
假设以A为根生成一颗树,如图所示V= {A},U-V = {B,C,D,D,F}。下一步要做的就是1.寻找arc[A][?]的最小值,同时找到顶点F 2.将F加入到V中。
接下来要做的就是不断重复上述操作。V = U。
注意:
候选最短边集在不断的更新,每加入一个顶点,都要对边集进行更新操作。
代码:
#include<iostream>
using namespace std;
const int Size = 100;
struct shortEdge
{
int adjvex;
int lowcost;
}sss[Size];
int arc[Size][Size];
int ver[Size];
int min(shortEdge a[],int n);
void init(int n,int e)
{
int i,j,k,flag;
for(i = 0;i < n;i ++)
for(j = 0;j < n;j ++){
if(i == j)arc[i][j] = 0;
else arc[i][j] = 10000;
}
for(i = 0;i < n;i ++){
ver[i] = i;
}
for(k = 0;k < e;k ++)
{
cin>>i>>j>>flag;
arc[i - 1][j - 1] = flag;
arc[j - 1][i - 1] = flag;
}
}
int min(shortEdge a[],int n)
{
int minCost = 10000;
int i,j;
for(i = 0;i < n;i ++){
if(a[i].lowcost != 0&&a[i].lowcost < minCost){
minCost = a[i].lowcost;
j = i;
}
}
return j;
}
int main()
{
int verNum,arcNum;
int i,j,k,root;
cin>>verNum>>arcNum>>root; //root表示节点 1~verNum,输入root选取根节点
init(verNum,arcNum);
for(i = 0;i < verNum;i ++){
sss[i].lowcost = arc[root - 1][i];
sss[i].adjvex = root - 1;
} //最短边集初始化
sss[root - 1].lowcost = 0;
for(i = 1;i < verNum;i ++){
k = min(sss,verNum); //选取权值最小的边
sss[k].lowcost = 0; //将顶点加入V中
cout<<"("<<(sss[k].adjvex + 1)<<","<<(k + 1)<<")";
for(j = 1;j < verNum;j ++){ //更新候补最短边集
if(arc[k][j] < sss[j].lowcost){
sss[j].lowcost = arc[k][j];
sss[j].adjvex = k;
}
}
}
return 0;
}
/*
6 10 1
1 2 6
1 3 1
1 4 5
2 3 5
3 4 5
2 5 3
5 3 6
3 6 4
6 4 2
5 6 6
ÑùÀýÊä³ö
(1,3)(3,6)(6,4)(3,2)(2,5)
*/