POJ_1251 (Java代码)

本文详细介绍了使用Kruskal算法和Prim算法解决POJ_1251最小生成树问题的过程,提供了完整的Java实现代码,并解释了关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POJ_1251链接 (最小生成树问题)

我写的是java代码、关于java自定义类型的编译器的、我弄了好久、现在总算通过了、自己也get了一个新知识、哈哈


import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;

public class POJ_1251_Kruskal {

    static int len, n;

    static Node[] node = new Node[80];
    static HashMap<String, String> fatherMap = new HashMap<String, String>(); // POJ 这里后面不能呢使用菱形运算符、会编译错误
    static LinkedList<Node> listNode = new LinkedList<Node>();  // POJ 这里后面不能呢使用菱形运算符、会编译错误
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        
        while (input.hasNext()) {
            listNode.clear();
            len = 0;
            n = input.nextInt();
            if (n == 0) {
                break;
            }
            for (int i = 0; i < n - 1; i++) {
                String u = input.next(); //  当前结点、、、
                fatherMap.put(u, u);  // 当前结点的父节点是自己、、、
                int num = input.nextInt(); // 能链接的岛屿的数量、、
                if (num == 0) {
                    continue;
                }
                for (int k = 0; k < num; k++) { // 与该岛屿连接的岛屿的信息、、、
                    String v = input.next();
                    fatherMap.put(v, v); // 当前结点的父节点 还是自己、、
                    int cost = input.nextInt();
                    listNode.add(new Node(u, v, cost));
                    len++; // 并且这个 记录边的总个数、、
                }
            }  // 岛屿输入的结束、、
            Collections.sort(listNode, new MyComparator()); // 用自己的定义的比较器初始化、、
            kruskal(listNode);
        }
    }

    private static void kruskal(LinkedList<Node> list) {
        int q = 0; // 添加的边数、、
        int ans = 0; // 花费、、
        for(int i = 0; i < len; i++){
            Node node = listNode.poll();
            if(Find(node.u) != Find(node.v)){
                ans += node.value;
                Union(node.u, node.v);
                q++;
            }
            if(q == n - 1) break;
        }
        System.out.println(ans);
    }

    public static void Union(String u, String v){
        String uFather = fatherMap.get(u);
        String vFather = fatherMap.get(v);
        if(uFather != vFather){
            fatherMap.put(uFather, vFather); // 合并起来、、
        }
    }
    
    public static String Find(String s){
        String father = fatherMap.get(s);
        if(father != s){
            father = Find(father);
        }
        fatherMap.put(s, father);
        return father;
    }
    
    public static class MyComparator implements Comparator<Node> {  // 自己定义的比较器、、、

        @Override
        public int compare(Node a, Node b) {
            return a.value - b.value;
        }
    }

    static class Node {

        String u, v;
        int value;

        public Node() {
        }

        public Node(String u, String v, int value) {
            this.u = u;
            this.v = v;
            this.value = value;
        }

    }
}

Prim算法注意的需要添加正反两个权重、

import java.util.Scanner;

public class POJ_1251_Prim {
    static final int INF = 0x3f3f3f;
    static int [][] map = new int [30][30];
    static boolean [] vis = new boolean [30]; // 用来标记有没有使用过的、、
    static int [] mincost = new int [30];
    static int n;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            Init();
            n = input.nextInt();
            if(n == 0) break;
            for(int i = 0; i < n - 1; i++){  // 
                String u = input.next();
                int unum = u.charAt(0) - 'A';// 总算转化出来了 、 java大法好、、、
                int num = input.nextInt();
                if(num == 0) continue;
                for(int k = 0; k < num; k++){
                    String v = input.next();  // 对应的边、、
                    int cost = input.nextInt(); //  权重 、、、
                    int vnum = v.charAt(0) - 'A'; 
                    map[unum][vnum] = map[vnum][unum] = cost;   //  Prim  无向边、两个都要添加、、
                } 
            }
            int res = Prim();
            System.out.println(res);
        }
    }
    
    public static int Prim(){
//        for(int i = 0; i < n; i++){  // 有也可以、没有也可以、、方便你们理解、、
//            vis[i] = false;
//            mincost[i] = map[0][i];
//        }
        mincost[0] = 0; // 起始位置为 0 、、
        int res = 0;
        while(true){
            int v = -1;
            for(int u = 0; u < n; u++){
                if(!vis[u] && (v == -1 || mincost[u] < mincost[v])){
                    v = u; // 找出当前最短的路径、、
                }
            }
            if(v == -1) break;
            vis[v] = true;
            res += mincost[v]; // 加上当前的长度、、、
            for(int u = 0; u < n; u++){
                mincost[u] = Math.min(mincost[u], map[v][u]);
            }
        }
        return res;
    }
    public static void Init(){
        for(int i = 0; i < 30; i++){
            vis[i] = false;
            mincost[i] = INF;
            for(int j = 0; j < 30; j++){
                map[i][j] = INF;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值