最小生成树

Kruskal算法

它把每条边排序,然后依次选取权值最小的边,当然,这个边必须能够带来一个新的顶点,如何判断是新顶点还是老顶点呢?很简单,用并查集把已选取的点放在一个集合里,未选取的点各自为营,选边的时候只需要判断一下,f[pre(e[i].u)]==f[pre[e[i].v]] (第一条边一定在集合里)因为只有两种集合,一种是被选中的,另一种没有
这思想算是一种贪心吧!

prim算法

它像Dijkstra一样有一个dist数组,用来记录主对象和其他对象的距离,与Dijkstra不同的是Dijkstra的主对象是一个固定的点,而prim算法的dist数组主对象是一颗在不断增加顶点的生成树。
随便从一个顶点出发,把他与其他点的距离作为dist(之所以可以随便从一个点出发是因为图的生成树要求图里的每一个它点都要有),然后不断找离dist最近的顶点(和Dijkstra一样挑中了就定下来了,这里 意味着它成为了最小生成树里的顶点),来更新它于其他对象的距离,接着继续找离dist最近的顶点,因为每次选的都是离dist最近的点,所以最后整个生成书也是最小的。

//通过最小元素来松弛最小树与其周围非树顶点的边
		for (int e = first0[k]; e!=-1; e=next0[e]){//这里用的是静态邻接表,e是离dist最近的顶点
			if (w[e] < dist[v[e]] && !book[v[e]]) {//如果能更新dist与其他点的距离而且这个点又没访问过
				dist[v[e]] = w[e];//更新距离,至于为什么这个点一定要是没访问过的点,这是因为一旦之前被选中的那些点他们与dist的距离被确定下来了,就像Dijkstra一样
				temp.i = v[e], temp.v = dist[v[e]];
				hep.push(temp);
			}
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值