最小生成樹的prim算法實現

      MST(Minimum Spanning Tree,最小生成樹)問題有兩種通用的解法,Prim算法就是其中之一,它是從點的方面考慮構建一顆MST,大致思想是:設圖G頂點集合爲U,首先任意選擇圖G中的一點作爲起始點a,將該點加入集合V,再從集合U-V中找到另一點b使得點b到V中任意一點的權值最小,此時將b點也加入集合V;以此類推,現在的集合V={a,b},再從集合U-V中找到另一點c使得點c到V中任意一點的權值
#include<iostream>
using namespace std;

#define MAX_SIZE 10
#define INF 9999;

typedef char ElemType;

typedef struct Graph
{
	int Matrix[MAX_SIZE+1][MAX_SIZE+1];
	ElemType v[MAX_SIZE+1];
	int vnum,linenum;
}Graph,*G;


int indexof(G &g,ElemType c)
{
	for(int i=1;i<=g->vnum;i++)
	{
		if(c==g->v[i])
		{
			return i;
		}
	}
	
	return -1;
}
void create_graph(G &g)
{
	g=(G)malloc(sizeof(Graph));
	ElemType c1,c2;
	int ind1,ind2,weight;
	//初始化
	for(int i=1;i<=MAX_SIZE;i++)
	{
		for(int j=1;j<=MAX_SIZE;j++)
		{
			if(i==j)
			{
				g->Matrix[i][j]=0;
			}else
			{
				g->Matrix[i][j]=INF;
			}
			
		}
	}

	cout<<"請輸入頂點數"<<endl;
	cin>>g->vnum;
	for(int i=1;i<=g->vnum;i++)
	{
		cout<<"請輸入第"<<i<<"個頂點"<<endl;
		cin>>g->v[i];
	}
	cout<<"請輸入總共有多少條邊"<<endl;
	cin>>g->linenum;
	for(int i=1;i<=g->linenum;i++)
	{
		cout<<"請輸入第"<<i<<"條邊的兩個頂點"<<endl;
		cin>>c1;
		cin>>c2;
		ind1=indexof(g,c1);
		ind2=indexof(g,c2);
		cout<<"請輸入第"<<i<<"條邊的權值"<<endl;
		cin>>weight;
		g->Matrix[ind1][ind2]=weight;
		g->Matrix[ind2][ind1]=weight;
		
	}
	
	//打印創建的矩陣
	for(int i=1;i<=g->vnum;i++)
	{
		for(int j=1;j<=g->vnum;j++)
		{
			cout<<g->Matrix[i][j]<<"   ";
		}
		cout<<endl;
	}

}

void prim(G &g)
{
	int isUsed[MAX_SIZE+1];//被加入最小生成樹的都置1
	int lowcost[MAX_SIZE+1];//存儲已生成最小生成樹中的點的集合到還未加入生成樹中的點的集合的最小值,
	//如lowcost[i]表示已生成樹到未生成的以i爲終點的 最小權值
	int ind[MAX_SIZE+1];//ind[i]存儲到以點i爲終點的邊的起點下標

	//從下標爲1的點開始,初始化如下
	for(int i=1;i<=MAX_SIZE;i++)
	{
		isUsed[i]=0;
		ind[i]=1;
		lowcost[i]=g->Matrix[1][i];
	}

	isUsed[1]=1;



	for(int i=2;i<=g->vnum;i++)
	{
		int min=INF;
		int k;
		

		//找到距離已生成樹的點集 具有最小權值的下標k,將其加入到最小生成樹點集合
		for(int j=1;j<=g->vnum;j++)
		{
			if(isUsed[j]==0&&lowcost[j]<min)
			{
				min=lowcost[j];
				k=j;
			}
				
		}
		isUsed[k]=1;


		//根據距離點k的最小權值更新lowcost和ind
		for(int j=1;j<=g->vnum;j++)
		{
			if(isUsed[j]==0&&g->Matrix[k][j]<lowcost[j])
			{
				lowcost[j]=g->Matrix[k][j];
				ind[j]=k;
			}
		}


	}
	for(int i=1;i<=g->vnum;i++)
	{
		cout<<"isUsed:"<<isUsed[i]<<"  ";
	}
	cout<<endl;
	for(int i=1;i<=g->vnum;i++)
	{
		cout<<"lowcost:"<<lowcost[i]<<"  ";
	}
	cout<<endl;
	for(int i=1;i<=g->vnum;i++)
	{
		cout<<"ind:"<<ind[i]<<"  ";
	}
	cout<<endl;

}
<span style="word-wrap: break-word; color: rgb(102, 102, 102);font-size:14px; line-height: 24px; font-family: 宋體;">該算法的時間複雜度爲</span><span lang="EN-US" style="word-wrap: break-word; color: rgb(102, 102, 102); font-family: 'Times New Roman';font-size:14px; line-height: 24px;"><span style="font-family:Times New Roman;word-wrap: break-word;">O(n2)</span></span><span style="word-wrap: break-word; color: rgb(102, 102, 102);font-size:14px; line-height: 24px; font-family: 宋體;">。與圖中邊數無關,該算法適合於稠密圖。</span>

void main()
{
	G g;
	create_graph(g);
	prim(g);
	system("pause");
}

最小,此時將c點加入集合V,直至所有頂點全部被加入V,此時就構建出了一顆MST。因爲有N個頂點,所以該MST就有N-1條邊,每一次向集合V中加入一個點,就意味着找到一條MST的邊。
發佈了54 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章