学习笔记:最小生成树算法

一、普里姆算法

①初始化新图仅包含原图中的任意一个顶点,不包含任何边。

②从原图中选择一条权值最小的边,该边满足有且仅有一个顶点在新图中。将该边加入新图。

③重复直至所有顶点都在新图中,新图即最小生成树。

二、克鲁斯卡尔算法

①初始化新图包含原图中的所有顶点,不包含任何边。

②从小到大遍历原图中所有边,若边中的两个顶点在新图中不存在连通路径,则将其加入新图。

③遍历结束后,新图即最小生成树。

三、实现

import java.util.TreeMap;
import java.util.TreeSet;

public class MinimumSpanningTree {
    public static class Edge implements Comparable<Edge> {
        int u, v, w;

        public Edge(int u, int v, int w) {
            this.u = u;
            this.v = v;
            this.w = w;
        }

        @Override
        public int compareTo(Edge e) {
            if (w != e.w) return w - e.w;
            else if (u != e.u) return u - e.u;
            else return v - e.v;
        }
    }

    public static TreeSet<Edge> prim(TreeSet<Integer> V, TreeSet<Edge> E) {
        TreeSet<Edge> T = new TreeSet<>();
        V.remove(V.first());
        while (!V.isEmpty())
            for (Edge e : E)
                if (V.contains(e.u) != V.contains(e.v)) {
                    V.remove(e.u);
                    V.remove(e.v);
                    T.add(e);
                    E.remove(e);
                    break;
                }
        return T;
    }

    public static TreeSet<Edge> kruskal(TreeSet<Integer> V, TreeSet<Edge> E) {
        TreeSet<Edge> T = new TreeSet<>();
        TreeMap<Integer, Integer> comp = new TreeMap<>();
        for (Integer v : V)
            comp.put(v, comp.size());
        for (Edge e : E) {
            if (comp.get(e.u).equals(comp.get(e.v)))
                continue;
            for (Integer i : comp.keySet())
                if (i != e.u && comp.get(i).equals(comp.get(e.u)))
                    comp.put(i, comp.get(e.v));
            comp.put(e.u, comp.get(e.v));
            T.add(e);
        }
        return T;
    }
}

相关推荐