楚楚街 寻宝

题目描述

亮亮解出了卷轴隐藏的秘密,来到了一片沼泽地。这里有很多空地,而面试直通卡可能埋在任意一块空地中,好在亮亮发现了一堆木材,他可以将木材铺在两个空地之间的沼泽地上。因为亮亮不知道面试直通卡具体在哪一块空地中,所以必须要保证任意一块空地对于亮亮来说是可以抵达的。 “怎么还有鳄鱼!没办法,看来有些空地不能直接到达了。” 亮亮虽然没有洁癖,但是沼泽地实在太臭了,所以亮亮不会循环利用木材。而且木材不能拼接在一起使用,所以亮亮必须要知道在耗费木材最少的情况下,最长的那根木材至少需要多长。

输入描述:
第一行包含两个整数N(1≤N≤10000),M(1≤M≤1000000)。N表示公有N块空地。
接下来M行,每行包含两个整数P(1≤P≤N),Q(1≤Q≤N),K代表P,Q两个间没有鳄鱼,需要耗费K的木材。

输出描述:
一个整数,即耗费木材最少的情况下,最长的那根木材长度。

输入例子:
4 3
1 2 1
2 3 1
3 4 2

输出例子:
2

/**
 * 求最小生成树的最大边
 * 并查集+最小生成树
 */
public class Main {

    static class Edge {
        public int x;
        public int y;
        public int val;

        public Edge(int x,int y,int val) {
            this.x = x;
            this.y = y;
            this.val = val;
        }
    }

    public static void main(String[] arg){
        Scanner scan=new Scanner(System.in);
        while(scan.hasNext()){
            String[] nm = scan.nextLine().split(" ");
            int n = Integer.parseInt(nm[0]);
            int m = Integer.parseInt(nm[1]);
            Edge[] edges = new Edge[m];
            for (int i = 0; i < m; i++) {
                String[] str = scan.nextLine().split(" ");
                int x = Integer.parseInt(str[0]);
                int y = Integer.parseInt(str[1]);
                int val = Integer.parseInt(str[2]);
                edges[i] = new Edge(x,y,val);
            }
            System.out.println(sovle(edges,n,m));
        }
        scan.close();
    }

    private static int sovle(Edge[] edges,int n,int m) {
        int res = 0;
        int[] father = new int[n+1];
        makeSet(father,n);
        //按边权值从小到大排序
        Arrays.sort(edges, new Comparator<Edge>() {
            @Override
            public int compare(Edge e1, Edge e2) {
                return e1.val - e2.val;
            }
        });
        for (int i = 0; i < m; i++) {
            int fx = findParent(father,edges[i].x);
            int fy = findParent(father,edges[i].y);
            if (fx != fy) {
                if (res < edges[i].val) {
                    res = edges[i].val;
                }
                UnionSet(father,fx,fy);
            }
        }
        return res;
    }

    private static void makeSet(int[] father,int n) {
        for (int i = 0; i <= n; i++) {
            father[i] = i;
        }
    }

    private static int findParent(int[] father,int x) {
        int r = x;
        while (father[r] != r) {
            r = father[r];
        }
        //路径压缩
        int i = x;
        while (i != r) {
            int j = father[i];
            father[i] = r;
            i = j;
        }
        return r;
    }

    private static void UnionSet(int[] father,int fx,int fy) {
        if (fx > fy) {
            father[fx] = fy;
        }else {
            father[fy] = fx;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值