最小生成树问题——Kruskal算法实现

本文通过龙门镖局镖局设计问题引入最小生成树问题,详细解析Kruskal算法的实现过程,包括如何判断两顶点是否在同一颗树上,避免形成环,以及如何选择权重最小的边。并提供了Java代码实现,利用并查集解决连通性和环的问题,以及快速排序确保边按权重排序。
摘要由CSDN通过智能技术生成

问题介绍

有一天我看到这么一个描述:古时候的镖局(相当于现在的快递公司)要押镖,然后有一张地图。地图上面清晰的标记了从A城市出发到B城市的每一条线路,所经过的每个城市。但是由于古时候绿林好汉太多了(还是社会主义好啊,扯远了~~~),两两城市之间绿林好汉收取的保护费是不一样的,所以这就导致压镖成本不同,那么怎样设计镖局所在地,才能使镖局能到达所有城市且打点绿林好汉的成本最少。问题描述完了,有没有觉得蛮有意思呢?那么经过模型化,其实上面问题就转化为:给你一个连通图,让你求它的最小生成树,最终满足图中两顶点之间有且仅有一条路径能到达,并且所有边的权重之后最小。如下图所示。
压镖路线开销图.png

问题分析

从问题描述中,为了满足问题需求,我们大致可以分析出以下几点:

  • 要让n个顶点连通(无向图,两两之间互通),至少需要n -1 条边;
  • 要让所有权重之后最小,应该从最小边开始逐个添加,直到添加满n -1条边为止;
  • 怎样确定添加的一条边是否满足“最小”的概念,有一点就是这条边不能形成环,也就是边两顶点不能已经是在“一颗树上”的;
  • 怎样判断两个顶点是否“在一棵树上”?用深度优先、广度优先都可以,但是时间复杂度比较高,所以我选择用并查集。

开始动手写代码

先上代码:

package disjointset;

import java.util.Scanner;

/**
 * 最小生成树问题
 * @author XZP
 * 一组测试用例
 6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2
 */
public class LongmenExpress {
   

	public static void main(String[] args) {
   
		int i = 0; // 循环计数变量
		int j = 1;
		int a, b, c; // a城到b城的花销c
		int count = 0; // 已经找到边的条数
		int sum = 0; // 最小生成树的开销总和
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(); // 城市总数
		int m = sc.nextInt(); // 道路总数
		Cost[] costs = new Cost[m + 1]; // 开销数组
		int[] book = new int [m + 1]; // 存储costs数组中对应的边是否被纳入最小生成树
		int[] f = new int[n + 1]; // 存储每个节点的父节点
		initF(f, n);
		for 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值