Search code examples
algorithmgraphbellman-ford

Given directed weighted graph that has one negeative edge (u,v), find shortest path (s,t)


Given: Directed, weighted graph G(V,E) and s,t are vertices of V, all edges are positive except the edge (u,v) which is negative.

Problem: Find the shortest path (Meaning: with the least weight) from s to t.

My solution: Well, because we have a negative edge we should use Bellman-Ford's algorithm. Doing n-1 "relax" on the edges, and if there's a problem in the n'th iteration there's a cycle - thus return false. otherwise, return the shortest path from s to t.

Another solution: Using Dijkstra, and changing it a bit by saving d(u) and passing on the negative edge (u,v) and doing "relax", then we go again on all the edges without the negative edge, if the distances were changed, we have a cycle, otherwise all good and return the shortest path.

Note: I'm obviously not sure about my solution, the fact that there is one negative edge is tricky, any ideas?

Note2: To make it interesting, you cannot use Bellman-Ford.


Solution

  • You can use the information that there is a single negative edge in order to create an efficient algorithm.

    Let's denote as a the source node of the negative edge, and b the destination node, so we have the negative edge a -> b.

    There are two kinds of paths from node s to node t:

    1. the edge a->b is not part of the path;
    2. the edge a->b is part of the path.

    We intend to find the shortest path from s to t, and we will do so by finding the shortest path of each of the above two types.


    The minimum path along the ones of type (1) can be found by simply applying Dijkstra's algorithm on the modified graph where the negative edge is removed.


    For type (2), we are now interested in the shortest path from s to t that contains the edge a->b. This path has to be of this form: s -> ... -> a -> b -> ... -> t.

    If we do not have negative cycles in the graph, then the edge a->b should appear only once in the shortest path (please see the final part of this answer for a discussion regarding negative cycles).

    In this situation (no negative cycles), we can apply Dijkstra's algorithm twice, first to find the shortest path from s to a; and then to find the shortest path from b to t. In both cases Dijkstra's algorithm should be applied on the graph modified by removing the negative edge a->b.


    Regarding negative cycles. If there is a negative cycle, i.e. a path that starts and ends in the same node and has negative cost, and that node is on a path from s to t, then a shortest path from s to t does not exist. Indeed, the cost from s to t can be made arbitrarily small in this case, by including the negative cost cycle multiple times.

    However, it is possible to determine if there is such a cycle in the graph, using again Dijkstra's algorithm. Note that since there is a single negative edge, a->b, the negative cycle needs to contain it. Thus we need to have a path from b to a whose total cost is smaller than the absolute value of the weight of a->b. We can check whether there is such a path by applying Dijkstra's algorithm, with starting node b and destination a. Again, Dijkstra's algorithm should be applied on the graph with the a->b edge removed (we are not interested in having it in the path), thus all edge weights are positive.