最小生成树 Prim

#define max INFINITY
typedef struct myGraph
{
	int num;
	int arc[m][n];
}Graph;

void Prim(Graph t)
//Prim 
//把节点划分为两个集合,标记集合和未标记集合
//维持一个记录表,里面是所有未标记集合到已标记集合的边的相应最小权重,lowerCost
//每次从记录表中选取从小的权重,把此边的未标记节点划入标记集合,从未标记集合中删除,打印这个变化节点。lowerCost[j] = 0;
//更新记录表 lowerCost
//继续上述循环,直到所有的点都被标记
//最小生成树完成

//lowerCost数组保存目前为止,到已标记节点的最小权值
//当lowerCost[j]为零时,表示这个点已经划入了已标记集合
//adj[j] 表示lowerCost[k]的上一个节点 (adj[j], k)便是对应的一条边
{
	int min, i, j, k;
	int adj[max]; // vertexs num
	int lowerCost[max]; // lowerCost so far
	lowerCost[0] = 0; 
	adj[0] = 0;
	for(j = 1; j < t.num; j++)
	{
		lowerCost[j] = t.arc[0][j];
		adj[j] = 0;
	}
	
	for(i = 1; i < t.num; i++)
	{
		min = INFINITY;
		j = 1; k = 0;
		while(j < t.num) //从记录表中搜寻最小权重的边,即变化节点j
		{
			if(lowerCost[j] != 0 && lowerCost[j] < min)
			{
				min = lowerCost[j];
				k = j;
			}
			j++;
		}
		printf("%d %d \n", adj[k], k); // 打印变化节点
		lowerCost[k] = 0; // 从未标记集合转移到标记集合
		for(j = 1; j < t.num; j++) // 更新记录表
		{
			if(lowerCost[j] != 0 && t.arc[k][j] < lowerCost[j])
			{
				lowerCost[j] = t.arc[k][j];
				adj[j] = k;
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/shidamowang/article/details/80399088