0
votes

I have a directed graph with non-negative weights on the edges.

My algorithm should do the following:

  • Get all paths from vertex u to vertex v.
  • Compute the minimum weighted edge on each path from u to v.
  • Compute the Maximum of the minimum weighted edges I computed from above.

What algorithm is good for this? I ask this because I can just go naively and implement the steps above as I've stated them (brute force).

I have a feeling it's a slight modification of Dijkstra's algorithm, but I'm not sure. Also, what would the time complexity be?

2
I would recommend consulting an algorithm textbook (or Wikipedia).charlesreid1

2 Answers

1
votes

I think we don't need dijkstra here. Suppose we picked the path with desired minmax edge. It obviously doesn't include edges with lesser weights. So the algorithm is

  • pick K most heavy edges
  • use dfs/bfs to check if v is reachable from u through this edges (f(K) is true)
  • if K1>K2 and f(K2) is true, then obviously f(K1) is true
  • so we can just run binary search over K

time complexity is O((N+M) log M) where N - number of vertices and M - number of edges

0
votes

Any algorithm that actually considers all paths from u to v will take exponential time, because there is an exponential number of such paths - consider a ladder, or a grid of 2xN nodes - to go from one end or the other in the long dimension you have at least N independent choices, so at least 2^N possible paths.

I think you can modify Dijkstra's algorithm to do this. There is psuedocode at https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Pseudocode. As a first modification, change line 6 to set all initial distances to zero. We need to think about invariants, and our first invariant can be that dist[v] is the maximum value for the minimum edge in a path to v, for all paths seen so far. As before we set prev[v] to undefined and add v to Q, the queue holding all nodes currently under consideration. As a final part of the initialisation we set dist[source] = infinity - not 0. You can think of this as a hack, or as a way of defining the minimum edge length in a path of length 0 from v to v that doesn't have any edges.

Now we have that Q contains all nodes where the maximum value for the minimum edge is still under consideration, and that this value for all such nodes will only ever increase. Now we remove from Q the node u with the maximum value of dist[u] - this is step 13 modified with min changed to max. For each neighbor v of u we compute min(dist[v], length(u, v)). This is a new candidate for the maximum possible minimum edge length along any path from source to u, so if this is larger than dist[u], we set dist[u] to this value. Note that this means that no element u of Q will ever have dist[u] set to a value greater than the value of dist[v] for the element v of Q we have just removed, which was a maximum such value in the queue at that time. This means that once we have removed an element v from the queue its value dist[v] has been calculated for good and cannot be increased by any subsequent calculation. Beware that we have just changed dist[u] for a node in our queue Q. If Q is implemented with a data structure such as a priority queue, this probably means that the implementation will have to remove u from the priority queue under the old value of dist[u] and then re-insert it under the new value of dist[u].

Correctness follows from the invariants - at each time we have dist[v] the maximum value of minimum edge along every path considered so far, and when we remove v from the queue we know - because it has a maximum value for everything still in the queue - that none of the other paths we could consider can possibly change that value.

The time taken to do this is the same as Dijkstra, and for the same reason. We enter every element into the queue once, in the beginning, and we remove every element from the queue once. This tells us how many times we execute the remove operation in line 14.

(Maximum of the minimum weighted edges seems an odd thing to calculate - is there an interesting application here, or is this an artificial exercise to get you to think about Dijkstra's algorithm?)