图——最小生成树(Prim算法)

本文介绍了使用Java实现的Prim算法,用于在无向图中找到具有最小边权和的最小生成树。算法通过优先队列管理和节点扩展来构造树并更新距离数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;

//意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小
// undirected graph only
public class Code05_Prim {

	public static class EdgeComparator implements Comparator<Edge> {

		@Override
		public int compare(Edge o1, Edge o2) {
			return o1.weight - o2.weight;
		}

	}

	public static Set<Edge> primMST(Graph graph) {
		//解锁的边进入小根堆(优先队列)
		PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(
				new EdgeComparator());
		HashSet<Node> set = new HashSet<>();
		Set<Edge> result = new HashSet<>();	//依次挑选的前边在result里
		for (Node node : graph.nodes.values()) {	//随便挑选一个点
			//如果set中不包含node,则将node加入set中
			if (!set.contains(node)) {
				set.add(node);
				//获取node的所有边
				for (Edge edge : node.edges) {		//由一个点解锁所有相连的边
					priorityQueue.add(edge);
				}
				//当小根堆不为空时
				while (!priorityQueue.isEmpty()) {
					//推出边edge,令toNode等于edge的出点
					Edge edge = priorityQueue.poll();
					Node toNode = edge.to;
					//如果set中不包含了这个出点,就加入set中,同时将边edge加入结果集result
					if (!set.contains(toNode)) {
						set.add(toNode);
						result.add(edge);
						//遍历
						for (Edge nextEdge : toNode.edges) {
							priorityQueue.add(nextEdge);
						}
					}
				}
			}
		}
		return result;
	}

	// 请保证graph是连通图
	// graph[i][j]表示点i到点j的距离,如果是系统最大值代表无路
	// 返回值是最小连通图的路径之和
	public static int prim(int[][] graph) {
		int size = graph.length;
		int[] distances = new int[size];
		boolean[] visit = new boolean[size];
		visit[0] = true;
		for (int i = 0; i < size; i++) {
			distances[i] = graph[0][i];
		}
		int sum = 0;
		for (int i = 1; i < size; i++) {
			int minPath = Integer.MAX_VALUE;
			int minIndex = -1;
			for (int j = 0; j < size; j++) {
				if (!visit[j] && distances[j] < minPath) {
					minPath = distances[j];
					minIndex = j;
				}
			}
			if (minIndex == -1) {
				return sum;
			}
			visit[minIndex] = true;
			sum += minPath;
			for (int j = 0; j < size; j++) {
				if (!visit[j] && distances[j] > graph[minIndex][j]) {
					distances[j] = graph[minIndex][j];
				}
			}
		}
		return sum;
	}

	public static void main(String[] args) {
		System.out.println("hello world!");
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值