閱讀986 返回首頁    go 阿裏雲 go 技術社區[雲棲]


最小生成樹算法

#include <stdio.h>
#include <string.h>

#define INFINITY 1000000    // 無窮大
#define MAX_VERTEX_COUNT 6 // 圖最多頂點數

// 圖的鄰接矩陣
typedef int Graph[MAX_VERTEX_COUNT][MAX_VERTEX_COUNT];

/************************************************************************/
/* 功能:用Prim算法實現構造最小生成樹
/* 參數:g--圖 
/*       vertexCount -- 圖的頂點數
/*       father -- 記錄頂點的雙親
/************************************************************************/
void Prim(Graph g, int vertexCount, int father[])
{
	int i, j, k;
    int lowCost[MAX_VERTEX_COUNT]; // 記錄從U到V-U具有最小代價的邊
	int closeSet[MAX_VERTEX_COUNT];// 記錄了該邊依附的在U中的頂點,v屬於V-U 
	int used[MAX_VERTEX_COUNT];    // 記錄頂點是否已經被選中放入到U集合中
	int min;

	// 這裏初始選中頂點為1號頂點,這是可以修改的,本程序以1號頂點為默認
	for (i = 0; i < vertexCount; i++)
	{
		// 最短距離初始化為其他節點到1號節點的距離
		lowCost[i] = g[0][i];

		// 標記所有節點的依附點皆為默認的1號節點
		closeSet[i] = 0;

		// 所有頂點均未被選中到U集合中
		used[i] = 0; 

		// U集合中還沒有頂點,所有值設為-1,表示無雙親
		father[i] = -1;
	}

	used[0] = 1; // 1號頂點選中,並加入到集合U中
	// 依次選取剩餘頂點加入到集合中
	for (i = 1; i < vertexCount; i++)
	{
		j = 0;
		min = INFINITY;

		// 找滿足條件的最小權值邊的頂點k及其編號
		for (k = 1; k < vertexCount; k++)
		{
			// 邊權值較小且不在生成樹中
			if (!used[k] && lowCost[k] < min)
			{
				min = lowCost[k]; // 選中頂點
				j = k;
			}
		}
		father[j] = closeSet[j]; // 記錄j號頂點的雙親
		used[j] = 1; // 將j號頂點選入到生成樹中

		// 打印邊即打印該邊連接的兩個頂點(權值最小)
		printf("%d %d\n",j + 1,closeSet[j] + 1);

		for (k = 1; k < vertexCount; k++)
		{
			// 繼續找邊權值更小的頂點
			if (!used[k] && g[j][k] < lowCost[k])
			{
				lowCost[k] = g[j][k]; // 更新最小權值
				closeSet[k] = j; // 記錄新的依附點
			}
		}
	}

}


int main()
{
	int i, j, weight;
    Graph g;
    int father[MAX_VERTEX_COUNT];
	int vertexCount;

	for (i = 0; i < MAX_VERTEX_COUNT; i++)
	{
		for (j = 0; j < MAX_VERTEX_COUNT; j++)
		{
			g[i][j] = INFINITY;
		}
	}

	// 構造圖
	while (scanf("%d%d%d", &i, &j, &weight) != EOF)
	{
		// 無向圖是對稱的
		g[i - 1][j - 1] = weight;
		g[j - 1][i - 1] = weight;
	}

	Prim(g, 6, father);

	return 0;
}

最後更新:2017-04-03 18:52:05

  上一篇:go 壓縮解壓縮文件(zip格式)
  下一篇:go 少寫一個“;”,帶來不一樣的結果