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

92

被折叠的 条评论
为什么被折叠?



