两个城市间路径的最小分数
题目概述
给定一个包含 n 个城市的图(可能不连通),以及若干双向道路及其距离。定义路径的分数为路径中道路的最小距离,求从城市 1 到城市 n 的所有路径中,分数的最小值。
思路分析
关键点:对于任何路径,其分数由路径中的最小边决定。因此,全局最小分数即为连接城市 1 和 n 的连通分量中所有边的最小值。无论路径如何绕,只要包含这条最小边,分数即为该边值。故问题转化为寻找该连通分量的最小边。
解法步骤
- 预处理邻接边最小值:记录每个节点所有邻接边中的最小值。
- 并查集确定连通分量:合并连通的城市,找到包含
1和n的连通分量。 - 遍历连通分量:收集该分量中所有节点的最小邻接边,取全局最小值。
代码解析
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;
}
};
代码细节说明
- 预处理邻接边最小值:遍历所有道路,更新每个节点
u和v的最小邻接边到cb中。 - 并查集操作:
- 初始化:每个节点的父节点初始为自身。
- 合并操作:将每条道路的两端点合并,确保连通性。
- 确定连通分量:通过查找
n的根节点tk,确定目标连通分量。 - 收集最小值:遍历所有节点,若属于该连通分量,则用其邻接边最小值更新最终结果。
复杂度分析
- 时间复杂度:并查集操作近似 \(O(m \alpha(n))\)(线性),预处理和遍历均为 \(O(m + n)\),整体 \(O(m + n)\)。
- 空间复杂度:\(O(n + m)\),存储并查集父数组和邻接边信息。
结尾
我想出去玩!

浙公网安备 33010602011771号