HDU1301 最小生成树

本文通过最小生成树的 FLASH 演示,详细介绍了最小生成树算法的实现过程,并通过 HDU1301 问题链接展示了具体的应用案例。通过构建邻接矩阵并运用普里姆算法,实现最小生成树的构建,最后输出所有边的总权重作为最终结果。

 

 

这里面是最小生成树的FLASH演示:最小生成树flash演示

 

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1301

 

package D0803;

import java.util.*;
public class HDU1301 {

	static int[][] G;
	static int[] dist;
	static int s = 0;

	public static void prime(int n) {
		boolean[] p = new boolean[n];
		for (int i = 0; i < n; i++) {
			p[i] = false;
			if (i != s)
				dist[i] = G[s][i];
		}
		p[s] = true;
		dist[s] = 0;
		for (int i = 0; i < n-1; i++) {
			int min = Integer.MAX_VALUE;
			int k = -1;
			for (int j = 0; j < n; j++) {
				if (!p[j] && dist[j] < min) {
					min = dist[j];
					k = j;
				}
			}
			if (k == -1)
				return;
			p[k] = true;
			for (int j = 0; j <n; j++) {
				if (!p[j] && dist[j] > G[k][j]) {
					dist[j] = G[k][j];
				}
			}
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n;
		while(sc.hasNext()){
			n = sc.nextInt();
			if(n==0)break;
			G = new int[n][n];
			for(int i = 0;i<n;i++)
				for(int j = 0;j<n;j++)
					G[i][j]=Integer.MAX_VALUE;
			dist = new int[n];
			for(int i = 1;i<n;i++){
				int u = sc.next().charAt(0)-'A';
				int r = sc.nextInt();
				while(r-- > 0){
					int v = sc.next().charAt(0)-'A';
					int w = sc.nextInt();
					if(G[u][v]>w){
						G[u][v]=w;
						G[v][u]=w;
					}
				}
			}
			prime(n);
			int sum = 0;
			for(int i = 0;i<n;i++)
				sum+=dist[i];
			System.out.println(sum);
		}
	}

}


 

 

package D0803;

import java.util.*;

public class HDU1301_2 {
	static class Edge implements Comparable<Edge> {
		int from;
		int to;
		int w;
		boolean select;

		public Edge(int f, int t, int ww) {
			from = f;
			to = t;
			w = ww;
		}

		@Override
		public int compareTo(Edge o) {
			if (w != o.w)
				return w - o.w;
			if (from != o.from)
				return from - o.from;
			return to - o.to;
		}
	}

	static int[] set;
	static int[] height;

	static void init(int n) {
		set = new int[n];
		height = new int[n];
		for (int i = 0; i < n; i++) {
			set[i] = i;
			height[i] = 1;
		}
	}

	// 合并集合
	public static void merge(int a, int b) {
		if (height[a] < height[b])
			set[a] = b;
		else if (height[a] > height[b])
			set[b] = a;
		else {
			set[b] = a;
			height[a]++;
		}
	}

	// 查找x属于哪个集合
	public static int find(int x) {
		while (set[x] != x)
			x = set[x];
		return x;

	}

	public static void kruskal(List<Edge> edges, int n) {
		Collections.sort(edges);
		int k = 0;
		for (int i = 0; i < edges.size(); i++) {
			if (k == n - 1)
				break;
			int x = find(edges.get(i).from);
			int y = find(edges.get(i).to);
			if (x != y) {
				merge(x, y);
				k++;
				edges.get(i).select = true;
			}
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n;
		while (sc.hasNext()) {
			n = sc.nextInt();
			if (n == 0)
				break;
			List<Edge> edges = new ArrayList<Edge>();
			init(n);
			for (int i = 1; i < n; i++) {
				int u = sc.next().charAt(0) - 'A';
				int r = sc.nextInt();
				while (r-- > 0) {
					int v = sc.next().charAt(0) - 'A';
					int w = sc.nextInt();
					Edge e = new Edge(u, v, w);
					edges.add(e);
				}
			}
			kruskal(edges, n);
			int sum = 0;
			for (int i = 0; i < edges.size(); i++)
				if (edges.get(i).select)
					sum += edges.get(i).w;
			System.out.println(sum);
		}
	}

}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怎么演

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值