最小生成树Prim算法

(1)问题描述:输入:一个边加权无向连通图G=(V,E);输出:最小代价生成树。

最小生成树:1.连接图中所有的顶点2.代价最小(所有边权重之和)的生成树。最小生成树Prim算法(2)引入概念:

1.图割:

无向图G =(V,E)的一个割(S,V-S),是集合V的一个划分。

a.如果E中一条边(u,v)的一个端点在S中,另一个端点在V-S中,则称这条边为横跨割(S,V-S)

b.如果集合A中不存在横跨割的边,则称该集合为割尊重。

c.在横跨该割的所有边中,权重最小的边称为轻量级边(该边不唯一)。

(3)算法思想:

加点法:

每次迭代选择轻量级边对应的点,假如到最小生成树中。算法从某一个顶点开始,逐渐长大直到覆盖整个连通图的所有顶点。(贪心思想)

示意图:

最小生成树Prim算法

(3)c++代码实现

//Graph是无向图,r是生成树的起始点

void prim(vector<vector<int>> &Graph,int r)
{

    int size = Graph.size();
    vector<int> visited(size);//设置访问标志变量
    visited[r]=1;//将起点设置为已访问
    vector<int> lowcost(size);
    for(int i = 0;i<size;i++)
    {
        lowcost[i] = INF;
    }
	cout << "0";
	int weight = 0;
	for (int i = 0; i < size; i++)
	{
		int min = 99999;
		int k = 1;
		for (int j = 0; j < size; j++)//找出当前割的轻量级边
		{
			if (lowcost[j] < min&&!visited[j])
			{
				min = lowcost[j];
				k = j;
			}
		}
		if (k == 1 && min == 99999)
		{
			cout << "\n最小生成树权值为:" << weight<<endl;
			return;
		}
		else
		{
			weight += min;
		}
		cout << " -> " << k;
		visited[k] = 1;
		for (int j = 1; j <size; j++)//轻量级边权值的更新
		{
			if ((VGraph[k][j]<lowcost[j]) && (!visited[j]))  
				lowcost[j] = Graph[k][j];				
			}
		}
	}
}

上一篇:220221-220222


下一篇:AI学习实习元旦小结