本文涉及知识点
C++图论 最短路
LeetCode1334. 阈值距离内邻居最少的城市
有 n 个城市,按从 0 到 n-1 编号。给你一个边数组 edges,其中 edges[i] = [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的双向加权边,距离阈值是一个整数 distanceThreshold。
返回在路径距离限制为 distanceThreshold 以内可到达城市最少的城市。如果有多个这样的城市,则返回编号最大的城市。
注意,连接城市 i 和 j 的路径的距离等于沿该路径的所有边的权重之和。
示例 1:
输入:n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4
输出:3
解释:城市分布图如上。
每个城市阈值距离 distanceThreshold = 4 内的邻居城市分别是:
城市 0 -> [城市 1, 城市 2]
城市 1 -> [城市 0, 城市 2, 城市 3]
城市 2 -> [城市 0, 城市 1, 城市 3]
城市 3 -> [城市 1, 城市 2]
城市 0 和 3 在阈值距离 4 以内都有 2 个邻居城市,但是我们必须返回城市 3,因为它的编号最大。
示例 2:
输入:n = 5, edges = [[0,1,2],[0,4,8],[1,2,3],[1,4,2],[2,3,1],[3,4,1]], distanceThreshold = 2
输出:0
解释:城市分布图如上。
每个城市阈值距离 distanceThreshold = 2 内的邻居城市分别是:
城市 0 -> [城市 1]
城市 1 -> [城市 0, 城市 4]
城市 2 -> [城市 3, 城市 4]
城市 3 -> [城市 2, 城市 4]
城市 4 -> [城市 1, 城市 2, 城市 3]
城市 0 在阈值距离 2 以内只有 1 个邻居城市。
提示:
2 <= n <= 100
1 <= edges.length <= n * (n - 1) / 2
edges[i].length == 3
0 <= fromi < toi < n
1 <= weighti, distanceThreshold <= 104
所有 (fromi, toi) 都是不同的。
多源最短路
多源最短路后,统计各节点小于等于阈值的数量。
代码
核心代码
template<class T = int >
class CFloyd
{
public:
CFloyd(int n, const T INF = 1000 * 1000 * 1000):m_INF(INF)
{
m_vMat.assign(n, vector<T>(n, m_INF));
for (int i = 0; i < n; i++) {
m_vMat[i][i] = 0;
}
}
void SetEdge(int i1, int i2,const T& dis, bool bDirect = false)
{
m_vMat[i1][i2] = min(m_vMat[i1][i2],dis);
if (!bDirect) {
m_vMat[i2][i1] = m_vMat[i1][i2];
}
}
vector<vector<T>> Dis()
{
auto vResMat = m_vMat;
const int n = m_vMat.size();
for (int i = 0; i < n; i++)
{//通过i中转
for (int i1 = 0; i1 < n; i1++)
{
if (m_INF == vResMat[i1][i])
{
continue;
}
for (int i2 = 0; i2 < n; i2++)
{
//此时:m_vMat[i1][i2] 表示通过[0,i)中转的最短距离
vResMat[i1][i2] = min(vResMat[i1][i2], vResMat[i1][i] + vResMat[i][i2]);
//m_vMat[i1][i2] 表示通过[0,i]中转的最短距离
}
}
}
return vResMat;
};
vector<vector<T>> m_vMat;//结果串
const T m_INF;
};
class Solution {
public:
int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
CFloyd floyd(n);
for (const auto& v : edges) {
floyd.SetEdge(v[0], v[1], v[2], false);
}
auto dis = floyd.Dis();
int iMax = INT_MAX,ans=-1;
for (int i = n - 1; i >= 0; i--) {
const int cnt = count_if(dis[i].begin(), dis[i].end(), [&](const int& val) {return val <= distanceThreshold; });
if (cnt < iMax) {
iMax = cnt;
ans = i;
}
}
return ans;
}
};