学习kruskal

转载 2013年12月03日 21:51:39
伪代码:

    把所有边排序,记第i小的边为e[i] (1<=i<m)

    初始化最小生成树为空

    初始化连通分量,让每一个点自成连通分量

    for(int i=0;i<m;i++)

    {

        if(e[i].u与e[i].v不在同一个连通分量)

         {

            把边e[i]加入到最小生成树中

            合并e[i].u和e[i].v所在的连通分量

         }

     }

    可用并查集优化

C++代码:

 

struct KRUSKAL
{
	const int MAXN = 109;
	const int MAXE = 5009;
 
	struct EDGE
	{
		int u, v, length, choose;
	}	edge[ MAXE ];
 
	int path[ MAXN ];
	int N, edgecnt, sum;
 
	void Addedge(int u, int v, int len)
	{
		++edgecnt;
		edge[ edgecnt ].u = u;
		edge[ edgecnt ].v = v;
		edge[ edgecnt ].length = len;
		edge[ edgecnt ].choose = false;
		return ;
	}
 
	void Set()
	{	
		for (int i = 1; i <= N; i++)
			path[i] = i;
		return ;
	}
 
	int Find_Path(int x)
	{
		if (x != path[x]) path[x] = Find_Path( path[x] );
		return path[x];
	}
 
	int Work()
	{
		int cnt = 0, x, y;
		Qsort(1, edgecnt);	// i < j -> edge[i].length < edge[j].length
		Set();
		for (int i = 1; i <= E && cnt < N - 1; i++)
		{
			x = Find_Path( edge[i].u );
			y = Find_Path( edge[i].v );
			if (x == y) continue;
			path[x] = path[y];
			edge[i].choose = true, ++cnt;
			sum += edge[i].length;
		}	
		return sum;
	}
}	Kruskal;

 

C++并查集优化代码:

 

#include <iostream>
using namespace std;
const int MAXV = 1024, MAXE = 100001;
int n, m, f[MAXV], ans, cnt;
struct edge{
	int f, t, w;
}es[MAXE];
bool cmp(const edge &a, const edge &b){
	return a.w < b.w;
}
void Fill(int &a){
	static int cnt = 0;
	a = ++cnt;
}
int get(int x){
	return x == f[x] ? x : f[x] = get(f[x]);
}
void Kruskal(const edge &e){
	if(get(e.f) != get(e.t)){
		f[get(e.f)] = get(e.t);
		ans += e.w;
		cnt++;
	}
}
void Read(edge &e){
	cin>>e.f>>e.t>>e.w;
}
int main()
{
	cin>>n>>m;
	for_each(es+1, es+m+1, Read);
	make_heap(es+1, es+m+1, cmp);
	sort_heap(es+1, es+m+1, cmp);
	for_each(f+1, f+n+1, Fill);
	for_each(es+1, es+m+1, Kruskal);
	cout<<(cnt < n-1 ? -1: ans)<<endl;
	return 0;
}



 

次小生成树模板(kruskal)

kruskal版的次小生成树。 struct data { int a,b,w; bool vis;///初始化0 } p[20010]; vectorg[110]; int f...
  • martinue
  • martinue
  • 2016年10月10日 20:05
  • 526

最小生成树-Kruskal算法(模板)

Kruskal基本算法:每次选取最短的边,看该边相连的两点是否在同一集合内,若在,则跳过,若不在,就把两个点合并,判断与合并都用并查集实现。 Kruskal的复杂度是O(ElogE),适合稀疏图。...
  • algzjh
  • algzjh
  • 2016年08月25日 10:49
  • 1165

贪心算法(Greedy Algorithm)之最小生成树 克鲁斯卡尔算法(Kruskal's algorithm)

克鲁斯卡尔算法(Kruskals algorithm)是两个经典的最小生成树算法的较为简单理解的一个。这里面充分体现了贪心算法的精髓。大致的流程可以用一个图来表示。这里的图的选择借用了Wikipedi...
  • hhygcy
  • hhygcy
  • 2009年04月10日 12:06
  • 15529

最小生成树Kruskal算法+并查集检查连通

/* 10 6 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 */ // 本例解决最小生成树问题 // 并查集来加快效率 /...
  • qq_21063873
  • qq_21063873
  • 2016年04月24日 14:52
  • 330

最小生成树-kruskal模板

表示之前一直只会prim,直到这一次专题赛被一道水题给坑了
  • u013700636
  • u013700636
  • 2014年08月12日 10:53
  • 589

最小生成树Prim与Kruskal算法的比较

最小生成树是图论问题中很基本的一个操作。常用的算法有Prim和Kruskal两种算法。本文对这两种算法稍作区别与讨论。Prim算法是依赖于点的算法。它的基本原理是从当前点寻找一个离自己(集合)最近的点...
  • Mollnn
  • Mollnn
  • 2016年09月19日 21:48
  • 3774

对次小生成树(Kruskal和prim)的理解

#include using namespace std; int n,m; struct data { int a,b,w; bool vis; } p[20010]; vector...
  • xiaosshhaa
  • xiaosshhaa
  • 2016年11月06日 20:28
  • 145

POJ 1751 Highways (Kruskal 最小生成树)

POJ 1751 Highways (Kruskal 最小生成树)
  • Tc_To_Top
  • Tc_To_Top
  • 2015年03月17日 23:51
  • 790

nyoj118次小生成树,由kruskal算法实现

修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利...
  • cai13160674275
  • cai13160674275
  • 2016年01月06日 22:20
  • 537

Kruskal算法证明及实现

Kruskal算法证明及实现 (2012-02-20 09:00:57) 1、算法概述 用于生成连通无向图的最小代价生成树。 2、算法步骤 步骤一:T是边的集合,其初始状态为空; 步骤...
  • nimingdenglu
  • nimingdenglu
  • 2012年06月29日 09:58
  • 906
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:学习kruskal
举报原因:
原因补充:

(最多只允许输入30个字)