我们在图的定义中说过,带有权值的图就是网结构。一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边。所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小。综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree)。找连通图的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法。
prim实现:
import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class Prim { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); int m = sc.nextInt(); if (n == 0 && m == 0) { break; } int[][] map = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { map[i][j] = Integer.MAX_VALUE; } } for (int i = 0; i < m; i++) { int u = sc.nextInt(); int v = sc.nextInt(); int w = sc.nextInt(); map[u][v] = w; map[v][u] = w; } Edge[] e = new Edge[n]; prim(map, e, n); for (int i = 0; i < n - 1; i++) { System.out.println(e[i].from + " " + e[i].end + " " + e[i].weight); } } } static void prim(int[][] map, Edge[] e, int n) { Set<Integer> set1 = new HashSet<>(); Set<Integer> set2 = new HashSet<>(); set1.add(0); for (int i = 1; i < n; i++) set2.add(i); int min = Integer.MAX_VALUE; int k=0; while (!set2.isEmpty()) { min = Integer.MAX_VALUE; int flag1 = 0; int flag2 = 0; for (int i : set1) { for (int j : set2) { if (map[i][j] < min) { min = map[i][j]; flag1 = i; flag2 = j; } } } set1.add(flag2); set2.remove(flag2); e[k]=new Edge(); e[k].from=flag1; e[k].end=flag2; e[k].weight=min; k++; } } private static class Edge { int from; int end; int weight; } }