最小生成树:
1.无向图
2.n个点由n-1条边联通(无环)
3.所有边的权值和最小
prim算法:
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
3).重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。
存储结构:一般用邻接矩阵
int mp[maxn][maxn],low[maxn],visited[maxn];//mp数组邻接矩阵存储图,low数组记录集合外的每个点与集合内的最小权值,visited数组标记某点是否已访问
int n;//n个点
int prim()
{
int pos,Min;//pos为刚加入的点,Min为当前情况下要加入边的权值(当前最小)
int result = 0;//存储最小权值和
memset(visited,0,sizeof(visited));
visited[1] = 1;//从某点开始,分别标记
pos = 1;//从某点开始,记录该点
for(int i = 1; i <= n; i++)
if(i != pos) low[i] = mp[pos][i];//初始化low数组
for(int i = 1; i < n; i++)//再运行n-1次(起点已经进入集合)使n个点全部进入集合
{
Min = INF;//找出最小权值并记录位置
for(int j = 1; j <= n; j++)
if(!visited[j] && Min > low[j])//对于每个点如果没有进入集合并且该点与集合的距离比当前的最小权值小则更新
{
Min = low[j];
pos = j;
}
result += Min;//最小权值累加
visited[pos] = 1;//标记该点,进入集合
for(int j = 1; j <= n; j++)//更新权值(刚进入的点对权值的影响)
if(!visited[j] && low[j] > mp[pos][j])
low[j] = mp[pos][j];
}
return result;
}