最小生成树

普里姆算法(Prim)

普里姆算法基本思想:从图中某个顶点V0开始,将V0到其他顶点的所有边当做候选边,重复以下步骤n-1次,使得其他n-1个顶点并入到树中:1、从候选边中挑选出权值最小的边输出,并将该边另一端相接的顶点V并入树中;2、考察所有剩余顶点Vi,如果(V,Vi)的权值比lowcost[Vi]小则用(V,Vi)的权值更新lowcost[Vi]。

普里姆算法模板

#define MAXN 101                //定义顶点的最大可达数
int n, sum;                          //顶点数,权值和
int map[MAXN][MAXN];         //以邻接矩阵存储权值

void prim()
{
	int vset[MAXN];     //记录顶点是否访问过
	int lowcost[MAXN]; //最小权值记录
	int i, j;
	for ( i=0; i<n; i++)
	{
		vset[i] = 0;
		lowcost[i] = map[0][i];
	}
	vset[0] = 1;
	int u, min;
	for ( i=1; i<n; i++)
	{
		min = 100001;
		for ( j=1; j<n; j++) //从备选边中选出最小边
		{
			if ( ! vset[j] && lowcost[j] < min && lowcost[j] > 0)
			{
				u = j;
				min = lowcost[j];
			}
		}

		vset[u] = 1;
		sum += min;
		for ( j=1; j<n; j++) //更新备选边
		{
			if (! vset[j] &&  map[u][j] < lowcost[j] )
				lowcost[j] = map[u][j];
		}
	}
}

克鲁斯卡尔算法(Kruskal)

克鲁斯卡尔算法基本思想:将图中边按照从小到大排序,然后从最小边开始扫描,并检测当前边是否是为候选边,即是否该边的并入会构成回路(使用并查集),如果不构成回路,则将该边并入当前生成树中,直到所有边都检测为止。

克鲁斯卡尔算法模板

#include <stdio.h>
#include <queue>
using namespace std;

const int Maxv =101;

typedef struct
{
	int from,to,cost;
}Node;

bool operator > (Node a,Node b)
{
	if( a.cost > b.cost )
		return true;
	return false;
}

int dis[Maxv][Maxv]; //dis以邻接矩阵形式表示一幅图 dis[i][j]为0时表示i点和j点不连通
int v[Maxv]; //并查集

int getRoot(int a)
{
    while(a!=v[a]) a=v[a];
    return a;
}

int main()
{
	int sum;
	priority_queue< Node,vector<Node>,greater<Node> > Q;  //返回最小数

	int vn,i,j;  
	while( scanf( "%d" , &vn ) != EOF )
	{
		//输入图部分
		for( i = 1 ; i <= vn ; i++ )
			for( j = 1 ; j <= vn ; j++ )
				scanf( "%d" , &dis[i][j] );
		for( i = 1 ; i <= vn ; i++ )   v[i] = i;	
		while( !Q.empty() )  Q.pop();
		//把每条边压入堆中
		for( i = 1 ; i < vn ; i++ )
			for( j = i+1 ; j <= vn ; j++ )
				if( dis[i][j] )
				{
					Node e;
					e.from = i , e.to= j , e.cost = dis[i][j];
					Q.push(e);
				}

		sum = 0;
		while( Q.size() != 0 )
		{
			Node e;
			e = Q.top();
			Q.pop();
			if( getRoot(e.from) != getRoot(e.to) )
			{
				sum += e.cost;
				v[getRoot(e.from)] = getRoot(e.to);
			}
		}

		printf( "%d\n" , sum );    //所需的最小值
	}
	
	return 0;
}

原文地址:https://www.cnblogs.com/flyoung2008/p/2137381.html