强烈建议首先阅读使用优先队列的 Dijkstra 算法。
最宽路径问题是在图的两个顶点之间找到一条路径的问题,使路径中的最小权重边的权重最大化。请参阅下图以了解问题所在:
实际应用示例:
这个问题是 Dijkstra 算法的一个著名变体。在实际应用中,这个问题可以看成一个以路由器为顶点的图,边代表两个顶点之间的带宽。现在如果我们想在互联网连接中找到两个地方之间的最大带宽路径,那么这个问题可以通过这个算法来解决。
如何解决这个问题呢?
我们将通过使用 Dijkstra 算法的优先级队列 ((|E|+|V|)log|V|) 来解决这个问题,并稍作改动。
我们通过将 Dijkstra 算法中的松弛条件替换为:
max(min(widest_dist[u], weight(u, v)), widest_dist[v])
其中 u 是 v 的源顶点。 v 是我们正在检查条件的当前顶点。
该算法适用于有向图和无向图。
请参阅下面的一系列图像以了解问题和算法:
边上的值表示有向边的权重。
我们将从源顶点开始,然后遍历与其相连的所有顶点,并根据松弛条件加入优先队列。
现在 (2, 1) 将弹出并且 2 将是当前的源顶点。
现在 (3, 1) 将从队列中弹出。但是由于 3 没有任何通过有向边连接的顶点,所以什么都不会发生。所以 (4, 2) 接下来会弹出。
最后算法停止,因为优先级队列中没有更多元素。
最宽距离最大值的路径是 1-4-3,最大瓶颈值为 2。所以我们最终得到最宽距离 2 以到达目标顶点 3。
下面是上述方法的实现:
CPP
// C++ implementation of the approach
#include
using namespace std;
// Function to print the required path
void printpath(vector& parent, int vertex, int target)
{
if (vertex == 0) {
return;
}
printpath(parent, parent[vertex], target);
cout << vertex << (vertex == target ? "\n" : "--");
}
// Function to return the maximum weight
// in the widest path of the given graph
int widest_path_problem(vector > >& Graph,
int src, int target)
{
// To keep track of widest distance
vector widest(Graph.size(), INT_MIN);
// To get the path at the end of the algorithm
vector parent(Graph.size(), 0);
// Use of Minimum Priority Queue to keep track minimum
// widest distance vertex so far in the algorithm
priority_queue, vector >,
greater > >
container;
container.push(make_pair(0, src));
widest[src] = INT_MAX;
while (container.empty() == false) {
pair temp = container.top();
int current_src = temp.second;
container.pop();
for (auto vertex : Graph[current_src]) {
// Finding the widest distance to the vertex
// using current_source vertex's widest distance
// and its widest distance so far
int distance = max(widest[vertex.second],
min(widest[current_src], vertex.first));
// Relaxation of edge and adding into Priority Queue
if (distance > widest[vertex.second]) {
// Updating bottle-neck distance
widest[vertex.second] = distance;
// To keep track of parent
parent[vertex.second] = current_src;
// Adding the relaxed edge in the prority queue
container.push(make_pair(distance, vertex.second));
}
}
}
printpath(parent, target, target);
return widest[target];
}
// Driver code
int main()
{
// Graph representation
vector > > graph;
int no_vertices = 4;
graph.assign(no_vertices + 1, vector >());
// Adding edges to graph
// Resulting graph
// 1--2
// | |
// 4--3
// Note that order in pair is (distance, vertex)
graph[1].push_back(make_pair(1, 2));
graph[1].push_back(make_pair(2, 4));
graph[2].push_back(make_pair(3, 3));
graph[4].push_back(make_pair(5, 3));
cout << widest_path_problem(graph, 1, 3);
return 0;
}
Python3
# Python3 implementation of the approach
# Function to print required path
def printpath(parent, vertex, target):
# global parent
if (vertex == 0):
return
printpath(parent, parent[vertex], target)
print(vertex ,end="\n" if (vertex == target) else "--")
# Function to return the maximum weight
# in the widest path of the given graph
def widest_path_problem(Graph, src, target):
# To keep track of widest distance
widest = [-10**9]*(len(Graph))
# To get the path at the end of the algorithm
parent = [0]*len(Graph)
# Use of Minimum Priority Queue to keep track minimum
# widest distance vertex so far in the algorithm
container = []
container.append((0, src))
widest[src] = 10**9
container = sorted(container)
while (len(container)>0):
temp = container[-1]
current_src = temp[1]
del container[-1]
for vertex in Graph[current_src]:
# Finding the widest distance to the vertex
# using current_source vertex's widest distance
# and its widest distance so far
distance = max(widest[vertex[1]],
min(widest[current_src], vertex[0]))
# Relaxation of edge and adding into Priority Queue
if (distance > widest[vertex[1]]):
# Updating bottle-neck distance
widest[vertex[1]] = distance
# To keep track of parent
parent[vertex[1]] = current_src
# Adding the relaxed edge in the prority queue
container.append((distance, vertex[1]))
container = sorted(container)
printpath(parent, target, target)
return widest[target]
# Driver code
if __name__ == '__main__':
# Graph representation
graph = [[] for i in range(5)]
no_vertices = 4
# Adding edges to graph
# Resulting graph
#1--2
#| |
#4--3
# Note that order in pair is (distance, vertex)
graph[1].append((1, 2))
graph[1].append((2, 4))
graph[2].append((3, 3))
graph[4].append((5, 3))
print(widest_path_problem(graph, 1, 3))
# This code is contributed by mohit kumar 29
1--4--3
2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。