Kruskal算法

      对于上面的图,我们对边进行排序,取前4条边就是一个最小生成树,这样的话,看起来似乎我们只需要对边进行排序,直到点的数量等于边的数量+1(所有的点已经有啦,再加就不是最小生成树了)。

    但是我们将第三条边和第8条边换一下,即A-D的权值为2,C-E的权值为8,那么之前的想法还对吗?,这时候当选A-D时就会形成回路了,即不是最小生成树了。那么我们是不是还要加条件呢,对了,我们还要加上并查集,我们将已经在生成树中的顶点存为一个集合,查询加入的边的两点是否和之前的顶点属于同一集合,若是不属于则加入,那么这就是krusual算法了。

代码如下:

​
package _图;

import java.util.Arrays;
import java.util.Scanner;

public class _Kruskal {

	static int[] par = new int[100];
	static int[] rank = new int[100];

	// 并查集初始化
	static void init(int n) {
		for (int i = 0; i < n; i++) {
			par[i] = i;
			rank[i] = 0;
		}
	}

	// 并查集查找
	static int find(int x) {
		if (par[x] == x)
			return x;
		else
			return par[x] = find(par[x]);
	}
	//合并集合
	static void unite(int x,int y) {
		x=find(x);
		y=find(y);
		if(x==y)
			return;
		else {
			if(rank[x]<rank[y]) {
				par[x]=y;
			}else {
				par[y]=x;
				if(rank[x]==rank[y])rank[x]++;
			}
		}
	}
	//判断是否同一集合
	static boolean same(int x,int y) {
		return find(x)==find(y);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int V=sc.nextInt();
		int E = sc.nextInt();
		Edge[] es = new Edge[E];
		for (int i = 0; i < E; i++)
			es[i] = new Edge();

		// 输入边
		for (int i = 0; i < es.length; i++) {
			int u = sc.nextInt();
			int v = sc.nextInt();
			int w = sc.nextInt();
			es[i].u = u;
			es[i].v = v;
			es[i].w = w;
		}
		// 边排序
		Arrays.sort(es);
		//并查集初始化
		init(V);
		int res=0;
        int k=0;
		for (int i = 0; i < E; i++) {
			Edge e=new Edge();
			if(!same(e.u,e.v)) {  //两个边不属于一个集合
				unite(e.u,e.v);
				res+=e.w;
                k++;
                if(k==n-1)break;//如果顶点已经是n个时,最小生成树已经完成。
			}
		}
		System.out.println(res);
	}

}

class Edge implements Comparable<Edge> {
	int u, v;
	int w;

	@Override
	public int compareTo(Edge o) {
		// TODO Auto-generated method stub
		if (w < o.w)
			return -1;
		else
			return 1;
	}
}

​

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kruskal算法是一种用来求加权连通图的最小生成树(MST)的算法,由Joseph Kruskal在1956年发表。该算法的基本思想是按照边的权值从小到大的顺序选择边,并保证这些边不构成回路。具体做法是首先构造一个只含有n个顶点的森林,然后依据权值从小到大从连通网中选择边加入到森林中,并保证森林中不产生回路,直至森林变成一棵树为止。 使用Kruskal算法求解最小生成树的过程主要有两个关键步骤。首先,需要对图的所有边按照权值大小进行排序。其次,需要判断在将边添加到最小生成树中时是否会形成回路。通过这两个步骤,Kruskal算法能够找到图的最小生成树。 总结来说,Kruskal算法通过按照边的权值从小到大选择边,并保证不形成回路的方式来构建最小生成树。这种算法适用于解决求解加权连通图的最小生成树问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Kruskal算法简易教程(附最全注释代码实现)](https://blog.csdn.net/hzf0701/article/details/107933639)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [克鲁斯卡尔算法Kruskal)详解](https://blog.csdn.net/weixin_45829957/article/details/108001882)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值