Prim算法——求无向图的最小生成树

1212 无向图最小生成树
基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题
 收藏
 关注
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
Output示例
37

具体过程就不多说,这是一个按点集求最小生成树的算法。

<pre name="code" class="objc">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> 
#define MaxInt 0x3f3f3f3f
typedef long long ll;
int map[1001][1001];    //邻接矩阵
int low[1001];          //记录2个点间最小权值 
int vis[1001];          //标记某点是否已访问
int n,m;                  //点的数量 
ll prim(){
	int i,j,pos,min;
	ll result=0;
	memset(vis,0,sizeof(vis)); //标记所有点没有被访问
	vis[1]=1;pos=1;      //从某点开始,分别标记和记录该点
	for(i=1;i<=n;i++)
		if(i!=pos)
			low[i]=map[pos][i]; //第一次给low数组赋值
	//运行n-1次,找出最小权值并记录位置	
	for(i=1;i<n;i++){
		min=MaxInt;
		for(j=1;j<=n;j++)
			if(vis[j]==0&&min>low[j]){
				min=low[j];
				pos=j;
			} 
		if(MaxInt==min)
			return -1;        //不连通 
		result=result+min;    //最小权相加
		vis[pos]=1;           //标记该点
		//更新权值
		for(j=1;j<=n;j++)
			if(vis[j]==0&&low[j]>map[pos][j])
				low[j]=map[pos][j]; 
	} 
	return result;
}
int main(){
	int i,j;
	while(scanf("%d %d",&n,&m)!=EOF){
		int x,y,w;
		memset(map,MaxInt,sizeof(map)); //首先记录所有边的权为最大值
		for(i=1;i<=m;i++){
			scanf("%d %d %d",&x,&y,&w);
			map[x][y]=map[y][x]=w;
		}	
		ll s=prim();
		printf("%lld\n",s); 
	}
	return 0;
}


 
   

你可能感兴趣的:(Prim算法——求无向图的最小生成树)