其他分享
首页 > 其他分享> > 最小生成树(Minimum Cost Spanning Tree)

最小生成树(Minimum Cost Spanning Tree)

作者:互联网

MST的性质
若(u, v)是一条具有最小权值的边,则存在一棵包含边(u, v)的最小生成树
最小生成树的算法就是基于MST这个性质写的
一、Prim算法
Prim算法也称为"加点法",从v0开始,根据MST的性质每次添加一条最小花费的顶点到集合U
Prim特有属性

class Closedge {    // closedge[]的作用是记录从U到V的最小花费和邻接边
    String adjvex;	// U集合到V-U集合的邻接顶点
    int lowcost;	// U集合到V-U集合的邻接边的权值
}
Closedge[] closedge;
closedge = new Closedge[VEXNUM];

Prim

public void Prim(String v0) {
    // 初始化closedge
    int x0 = Locate(v0);
    for (int i = 0; i < VEXNUM; i++) {
        closedge[i] = new Closedge(null, INF);
    }
    for (int i = 0; i < VEXNUM; i++) {
        if (i != x0){
            closedge[i].adjvex = v0;
            if (arcs[x0][i] < INF){
                closedge[i].lowcost = arcs[x0][i];
            }
        }
    }
    closedge[x0].lowcost = 0;

    // 利用MST的性质,每次添加最小花费的节点进入集合
    for (int w = 1; w < VEXNUM; w++) {
        // 找到closedge中的最小花费及其对应顶点
        int min = INF;
        int k = -1;
        for (int i = 0; i < VEXNUM; i++) {
            if (closedge[i].lowcost!=0 && min>closedge[i].lowcost){
                min = closedge[i].lowcost;
                k = i;
            }
        }

        // 根据顶点更新closedge信息
        closedge[k].lowcost = 0;
        for (int i = 0; i < VEXNUM; i++) {
            if (arcs[k][i] < closedge[i].lowcost){
                closedge[i].lowcost = arcs[k][i];
                closedge[i].adjvex = vexs[k];
            }
        }
    }
}

二、Kruskal算法
kruskal的特有属性

class Edge implements Comparable{	// edge[]用来记录各边,Edge类实现了Comparable用来根据边的权值排序edge[]
    int head, tail;
    int lowcost;
    
    @Override
    public int compareTo(Object o) {
        return this.lowcost - ((Edge) o).lowcost;
    }
}
public static ArrayList<Edge> edges;    // 记录各条边的信息
edges = new ArrayList<>();
public static Integer[] vexset; // 记录各个顶点所属连通分量
vexset = new Integer[VEXNUM];

Kruskal过程

public void Kruskal() {
    // 初始化边集合
    for (int i = 0; i < VEXNUM; i++) {
        for (int j = i+1; j < VEXNUM; j++) {
            if (arcs[i][j]!=INF)
                edges.add(new Edge(i, j, arcs[i][j]));
        }
    }

    // 初始化vexset
    for (int i = 0; i < VEXNUM; i++) {
        vexset[i] = new Integer(i);
    }

    Collections.sort(edges);     // 对边集合进行排序

    // 添加边到集合中
    for (int i = 0; i < ARCNUM; i++) {
        int vs0 = vexset[edges.get(i).head];
        int vs1 = vexset[edges.get(i).tail];

        if (vs0 != vs1){    // 更新vs1节点所在连通分量
            System.out.println(edges.get(i));   // 访问该边
            for (int j = 0; j < VEXNUM; j++) {
                if (vs1 == vexset[j]){
                    vexset[j] = vs0;
                }
            }
        }
    }
}
ziyang0421 发布了6 篇原创文章 · 获赞 5 · 访问量 6675 私信 关注

标签:VEXNUM,int,Tree,++,closedge,Minimum,lowcost,vexset,Cost
来源: https://blog.csdn.net/qq_41596915/article/details/104097850