最小生成树(prim)算法

算法描述:

    1:输入:一个加权连通图,其中顶点集合为V,边集合为E;

    2:初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空3

    3: 重复下列操作,直到Vnew = V:

                a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,

               而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);

               b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;

    4:输出:使用集合Vnew和Enew来描述所得到的最小生成树。

简单点说

    设顶点集合为V,最小生成树集合为S,初始化S为空,V为全部顶点的集合,

    第一步:  把定点1从V集合拿到S集合

   重复一下操作:

                        从S-V中选择一点到V集合最短的边,加入到集合S,

                       更新V集合到S集合各点的最短路

   以上操作直到S=V

上代码

void init1()
{
	scanf("%d%d", &N, &M);
	int Start, End, val;
	for (int i = 0; i < M; i++) {
		scanf("%d%d%d", &Start, &End, &val);
		maps[Start][End] = val;
	}
}

//prim算法
void prim()
{   
	int dis[1000];
	int vis[1000];
	memset(vis,0,sizeof(vis));
	int i,j,k,tmp,ans;
	for(i = 1; i <= N; i++) {
		dis[i] = inf;//初始化 
	}
	dis[1]=0;
	for(i = 1; i <= N; i++){
		tmp=inf;
		for(j = 1;j <= N; j++){
			if(!vis[j] && tmp>dis[j]){
				tmp = dis[j];								
				k = j;
			}//找出最小距离的节点 
		}
		vis[k] = 1;//把访问的节点做标记
		pResult += dis[k];
		for(j = 1;j <= N; j++){
			if(!vis[j] && dis[j] > maps[k][j]) {
				dis[j] = maps[k][j];//更新最短距离
			}
		}
	}	
}

int main()
{
	
	init1();
	printf("M:%d, N:%d\n", M,N);
	prim();		
	
	printf("%d\n", pResult);
}



//1 2 6
//
//1 3 1
//
//1 4 5
//
//2 3 5
//
//2 5 3
//
//3 4 5
//
//3 5 6
//
//3 6 4
//
//4 6 2
//
//5 6 6

    待调试

点赞