最小生成樹算法

簡介:最小生成樹算法一共有兩種,分別是kruskal算法和prim算法。也屬於貪心算法,它的目的就是給定無向圖、權值以及頂點,求聯通所有邊的權值和最小。
kruskal算法:
先構造一個只含 n 個頂點、而邊集爲空的子圖,把子圖中各個頂點看成各棵樹上的根結點,之後,從網的邊集 E 中選取一條權值最小的邊,若該條邊的兩個頂點分屬不同的樹,則將其加入子圖,即把兩棵樹合成一棵樹,反之,若該條邊的兩個頂點已落在同一棵樹上,則不可取,而應該取下一條權值最小的邊再試之。依次類推,直到森林中只有一棵樹,也即子圖中含有 n-1 條邊爲止。
這個算法實現就是先利用快排把從小到大排序,貪心算法取最優邊,然後利用並查集判斷兩邊是否已經在一個集合中。
核心代碼:

		for(i=1;i<=m;i++)//開始從小到大枚舉每一條邊
		{
			if(merge(e[i].u,e[i].v))//利用並查集判斷兩個邊是否已經在一個集合中
			{
				count++;
				sum=sum+e[i].w;
			}
			if(count==n-1)//到n-1條邊後退出循環
				break;
		}

prim算法:
算法流程:
1、從任意一個頂點構造生成樹,然後用book[]數組記錄標記的點。
2、用dis[]數組記錄生成樹到各個頂點的距離
3、從dis[]數組中選出離生成樹最近的頂點加入生成樹中,如果dis[k]>e[j][k],則重新更新dis[k]。
4、重複第三步,直到count==n.
核心代碼:

	book[1]=1;//將1號頂點加入生成樹
	count++;
	while(count<n)
	{
		min=inf;
		for(i=1;i<=n;i++)
		{
			if(book[i]==0&&dis[i]<min)
			{
				min=dis[i];
				j=i;
			}
		}
		book[j]=1;
		count++;
		sum+=dis[j];
		for(k=1;k<=n;k++)//掃描當前j所在的頂點,再以j爲中間點,更新生成樹到每一個非樹頂點的位置 
		{
			if(book[k]==0&&dis[k]>e[j][k])
				dis[k]=e[j][k];
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章