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

题目链接

题目概述

给定一个包含 n 个城市的图(可能不连通),以及若干双向道路及其距离。定义路径的分数为路径中道路的最小距离,求从城市 1 到城市 n 的所有路径中,分数的最小值。

思路分析

关键点:对于任何路径,其分数由路径中的最小边决定。因此,全局最小分数即为连接城市 1n 的连通分量中所有边的最小值。无论路径如何绕,只要包含这条最小边,分数即为该边值。故问题转化为寻找该连通分量的最小边。

解法步骤

  1. 预处理邻接边最小值:记录每个节点所有邻接边中的最小值。
  2. 并查集确定连通分量:合并连通的城市,找到包含 1n 的连通分量。
  3. 遍历连通分量:收集该分量中所有节点的最小邻接边,取全局最小值。

代码解析

class Solution {
public:
    int minScore(int n, vector<vector<int>>& roads) {
        unordered_map<int,int>cb;
        int m=roads.size(),re=1e6;
        for(auto x:roads){
            if(cb[x[0]]!=0)cb[x[0]]=min(cb[x[0]],x[2]);
            else cb[x[0]]=x[2];
            if(cb[x[1]]!=0)cb[x[1]]=min(cb[x[1]],x[2]);
            else cb[x[1]]=x[2];
        }
        vector<int>p(n+1);
        for(int i=1;i<=n;i++)p[i]=i;
        auto fin=[&](auto &&fin,int a){
            if(p[a]==a)return a;
            else return p[a]=fin(fin,p[a]);
        };
        for(int i=0;i<m;i++){
            int x=fin(fin,roads[i][0]);
            int y=fin(fin,roads[i][1]);
            if(x!=y){
                p[x]=y;
            }
        }
        for(int i=1;i<=n;i++)fin(fin,i);
        int tk=fin(fin,n);
        for(int i=1;i<=n;i++){
            if(p[i]==tk){
                re=min(re,cb[i]);
            }
        }
        return re;
    }
};

代码细节说明

  1. 预处理邻接边最小值:遍历所有道路,更新每个节点 uv 的最小邻接边到 cb 中。
  2. 并查集操作
    • 初始化:每个节点的父节点初始为自身。
    • 合并操作:将每条道路的两端点合并,确保连通性。
  3. 确定连通分量:通过查找 n 的根节点 tk,确定目标连通分量。
  4. 收集最小值:遍历所有节点,若属于该连通分量,则用其邻接边最小值更新最终结果。

复杂度分析

  • 时间复杂度:并查集操作近似 \(O(m \alpha(n))\)(线性),预处理和遍历均为 \(O(m + n)\),整体 \(O(m + n)\)
  • 空间复杂度\(O(n + m)\),存储并查集父数组和邻接边信息。

结尾

我想出去玩!

posted @ 2025-03-21 00:04  Xhita  阅读(40)  评论(0)    收藏  举报