太原理工大学2021软件学院数据结构课程设计第二题(构造可以使n个城市连接的最小生成树)核心代码(2021.6.6)

Posted 卷王2048

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了太原理工大学2021软件学院数据结构课程设计第二题(构造可以使n个城市连接的最小生成树)核心代码(2021.6.6)相关的知识,希望对你有一定的参考价值。

太原理工大学2021软件学院数据结构课程设计第二题(构造可以使n个城市连接的最小生成树)核心代码(2021.6.6)

声明:这里只是给出核心代码

核心代码指程序的计算部分,不是完整程序

题目背景:P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目

题目描述

如题,给出一个向图,求出最小生成树,如果该图不连通,则输出 orz

输入格式

第一行包含两个整数 N,M,表示该图共有 N 个结点和 M 条无向边。

接下来 M 行每行包含三个整数xi,yi,zi,表示有一条长度为zi的无向边连接结点 xi,yi.

输出格式

如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz

输入输出样例

**输入 **

4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3

输出 #1

7

最小生成树背景知识

1.最小生成树的代价指最小生成树各边长度之和

在这里插入图片描述
在这里插入图片描述

Kruscal算法代码

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @see 图论 Kruscal https://www.luogu.com.cn/problem/P3366 https://www.acwing.com/solution/content/30279/
 */
public class Main {

    static class Edge {
        int a, b, w;

        public Edge(int a, int b, int w) {
            this.a = a;
            this.b = b;
            this.w = w;
        }
    }

    static final int N = 100010;
    static int n, m;
    static int[] p;
    static Edge[] edges;

    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

    static int nextInt() throws Exception {
        in.nextToken();
        return (int) in.nval;
    }

    static String next() throws Exception {
        in.nextToken();
        return in.sval;
    }

    /**
     * 并查集find模板
     * @param x 当前连通块的点
     * @return
     */
    static int find(int x) {
        if (p[x]!=x){
            p[x] = find(p[x]);
        }
        return p[x];
    }

    static int kruskal() {
        Arrays.sort(edges, Comparator.comparingInt(a -> a.w));
        for (int i = 1; i <= n; i++) {
            p[i] = i;
        }
        int res = 0, count = 0;
        for (int i = 0; i < m; i++) {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a);
            b = find(b);
            if (a != b) {
                p[a] = b;
                res += w;
                count++;
            }
        }
        //判断是否连通
        return count < n - 1 ? -1 : res;

    }

    public static void main(String[] args) throws Exception {
        n = nextInt();
        m = nextInt();
        edges = new Edge[m];
        p = new int[n + 1];

        for (int i = 0; i < m; i++) {
            int a = nextInt();
            int b = nextInt();
            int c = nextInt();
            edges[i] = new Edge(a, b, c);

        }
        int ans = kruskal();
        if (ans==-1){
            System.out.println("orz");
        }else {
            System.out.println(ans);
        }

    }


}

Prim算法代码

package Acwing858Prim算法求最小生成树;

import java.io.*;
import java.util.Arrays;

/**
 * @see 图论 最小生成树 Prim https://www.acwing.com/solution/content/38312/ https://www.luogu.com.cn/problem/P3366
 */
public class PrimClass {
    static final int INF = 9999;
    static int[][] ad;
    static int[] dist;
    static int n, m;
    static boolean[] st;

    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

    static int nextInt() throws Exception {
        in.nextToken();
        return (int) in.nval;
    }

    static int prim() {
        Arrays.fill(dist, INF);
        int res = 0;
        for (int i = 0; i < n; i++) {
            int t = -1;
            for (int j = 1; j <= n; j++) {
                if (!st[j] && (t == -1 || dist[j] < dist[t])) {
                    t = j;
                }
            }
            if (i > 0 && dist[t] == INF) {
                return INF;
            }
            if (i > 0) {
                res += dist[t];
            }
            for (int j = 1; j <= n; j++) {
                dist[j] = Math.min(dist[j], ad[t][j]);
            }
            st[t] = true;

        }
        return res;
    }

    public static void main(String[] args) throws Exception {
        n = nextInt();
        m = nextInt();
        dist = new int[n+1];
        ad = new int[n+1][n+1];
        st = new boolean[n+1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (i == j) {
                    ad[i][j] = 0;
                } else {
                    ad[i][j] = INF;
                }
            }
        }

        while (m-- > 0) {
            int a = nextInt();
            int b = nextInt();
            int c = nextInt();
            ad[a][b] = Math.min(ad[a][b], c);
//-------------无向图-----------------------------
            ad[b][a]= ad[a][b];
//-----------------------------------------------
        }
        int ans = prim();
        if (ans == INF) {
            System.out.println("orz");
        } else {
            System.out.println(ans);
        }


    }


}

再次强调,以上只是核心代码,同学们要根据核心代码,自己编写完整的程序

完整程序应该是这样

在这里插入图片描述

刷题不迷路,欢迎关注博主的git题集,这里有最详细的分类,最经典的例题和最全面的注释


在这里插入图片描述

感兴趣的同学可以赏个star吗:算法刷题集git地址       题目源码地址

以上是关于太原理工大学2021软件学院数据结构课程设计第二题(构造可以使n个城市连接的最小生成树)核心代码(2021.6.6)的主要内容,如果未能解决你的问题,请参考以下文章

太原理工大学这两年程序设计等竞赛奖牌统计

2021年太原理工大学程序设计竞赛等获奖总结

2021团体程序设计天梯赛-太原理工成绩大跃进

第45届国际大学生程序设计竞赛(ICPC)银川站太原理工大学收获4枚奖牌

蓝桥杯2021国赛太原理工大学获得14枚奖牌

educoder头歌实训 太原理工大学web课程————JavaScript对象:数组