给定 N 个节点和M 条边的有向加权图,任务是找到从节点1到N的第 1 到第K 条最短路径长度。
例子:
Input: N = 4, M = 6, K = 3, edges = {{1, 2, 1}, {1, 3, 3}, {2, 3, 2}, {2, 4, 6}, {3, 2, 8}, {3, 4, 1}}
Output: 4 4 7
Explanation: The shortest path length from 1 to N is 4, 2nd shortest length is also 4 and 3rd shortest length is 7.
Input: N = 3, M = 3, K = 2, edges = {{1, 2, 2}, {2, 3, 2}, {1, 3, 1}}
Output: 1 4
方法:思想是使用BFS遍历图的所有顶点,并使用优先级队列来存储尚未确定最短距离的顶点,并获得最小距离顶点。请按照以下步骤操作。
- 初始化一个优先级队列,比如大小为N 的pq来存储顶点数和距离值。
- 初始化一个二维向量,比如大小为N*K 的dis ,并用非常大的数字初始化所有值,比如 1e9。
- 将dis[1][0]设置为零,即源顶点的距离值。
- 在pq不为空时迭代。
- 从 pq 中弹出值,并将顶点值存储在变量u 中,将顶点距离存储在变量d 中。
- 如果d大于距离u ,则继续。
- 对于u的每一个相邻顶点v ,检查第K个距离值是否大于uv的权重加上u的距离值,然后更新v的第K个距离值,并对顶点v的k个距离进行排序。
下面是上述方法的实现:
C++14
// C++ implementation of above approach
#include
using namespace std;
// Function to find K shortest path lengths
void findKShortest(int edges[][3], int n, int m, int k)
{
// Initialize graph
vector > > g(n + 1);
for (int i = 0; i < m; i++) {
// Storing edges
g[edges[i][0]].push_back({ edges[i][1], edges[i][2] });
}
// Vector to store distances
vector > dis(n + 1, vector(k, 1e9));
// Initialization of priority queue
priority_queue,
vector >,
greater > >
pq;
pq.push({ 0, 1 });
dis[1][0] = 0;
// while pq has elements
while (!pq.empty()) {
// Storing the node value
int u = pq.top().second;
// Storing the distance value
int d = (pq.top().first);
pq.pop();
if (dis[u][k - 1] < d)
continue;
vector > v = g[u];
// Traversing the adjacency list
for (int i = 0; i < v.size(); i++) {
int dest = v[i].first;
int cost = v[i].second;
// Checking for the cost
if (d + cost < dis[dest][k - 1]) {
dis[dest][k - 1] = d + cost;
// Sorting the distances
sort(dis[dest].begin(), dis[dest].end());
// Pushing elements to priority queue
pq.push({ (d + cost), dest });
}
}
}
// Printing K shortest paths
for (int i = 0; i < k; i++) {
cout << dis[n][i] << " ";
}
}
// Driver Code
int main()
{
// Given Input
int N = 4, M = 6, K = 3;
int edges[][3] = { { 1, 2, 1 }, { 1, 3, 3 },
{ 2, 3, 2 }, { 2, 4, 6 },
{ 3, 2, 8 }, { 3, 4, 1 } };
// Function Call
findKShortest(edges, N, M, K);
return 0;
}
输出
4 4 7
时间复杂度: O((N+M)*KlogK)
辅助空间: O(NK)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。