leetcode2492. 两个城市间路径的最小分数

题目

给你一个正整数 n ,表示总共有 n 个城市,城市从 1 到 n 编号。给你一个二维数组 roads ,其中 roads[i] = [ai, bi, distancei] 表示城市 ai 和 bi 之间有一条 双向 道路,道路距离为 distancei 。城市构成的图不一定是连通的。

两个城市之间一条路径的 分数 定义为这条路径中道路的 最小 距离。

城市 1 和城市 n 之间的所有路径的 最小 分数。

注意:

一条路径指的是两个城市之间的道路序列。

一条路径可以 多次 包含同一条道路,你也可以沿着路径多次到达城市 1 和城市 n 。

测试数据保证城市 1 和城市n 之间 至少 有一条路径。

问题解析

这个题目实际上就是连通图分组的问题。根据各个点的连通关系,可以把原始图分成若干个连通图。又因为题目里说“保证城市 1 和城市n 之间 至少 有一条路径”,所以1,n一定在一个连通图里,那么此时这个图里的最短路径就是问题答案。

所以思路到这就比较明确了,可以用并查集的思想,把原始图做分组,然后找到1所在的组,求得最小值。

代码实现

import java.util.*;

class Solution {
    public int minScore(int n, int[][] roads) {
        UnionFind unionFind = new UnionFind(n);
        for(int i=0;i<n;i++){
            unionFind.add(i);
        }
        for(int i=0;i<roads.length;i++){
            int [] disArr = roads[i];
            int start = disArr[0];
            int end = disArr[1];
            //各自所属的集合,不是同一个,那就把这俩合并
            if(!unionFind.isConnected(start-1,end-1)){
                unionFind.merge(start-1,end-1);     
            }
        }
        int minDis = 1000000;
        for(int i=0;i<roads.length;i++){
            int [] disArr = roads[i];
            int start = disArr[0];
            int end = disArr[1];
            int dis = disArr[2];
            //只要判断start,end中的一个即可
            if(unionFind.isConnected(0,start-1)){
                minDis = Math.min(minDis,dis);
            }
        }
        return minDis;
    }
}

//并查集类
class UnionFind {
    //
    private int[] father;
    private int size;

    public UnionFind(int n){
        father = new int[n];
        size = 0;
    }

    //初始化的时候,每个人的父亲是自己
    public void add(int x){
        father[x] = x;
        size ++;
    }

    //找祖宗,找的过程也会重新赋值
    public int findFather(int x){
        if(father[x]!=x){
            father[x] = findFather(father[x]);
        }
        return father[x];
    }
    //把两个集合合并在一起,选出新的父亲
    public void merge(int x,int y){
        int xFather = findFather(x);
        int yFather = findFather(y);
        //直接把x合并到y的集合中。也就是把x的祖宗,指向y的祖宗
        if(xFather != yFather){
            father[xFather] = yFather;
            size--;
        }
    }
    //判断祖宗是否一样
    public boolean isConnected(int x,int y){
        return findFather(x) == findFather(y);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值