Describing an algorithm at most O(nm log n) run time - algorithm

If I had to give an algorithm in O|V|3| that takes as input a directed graph with positive edge lengths and returns the length of the shortest cycle in the graph (if the graph is acyclic, it should say so). I know that it will be:
Let G be a graph, define a matrix Dij which stores the shortest path from vertex i to j for any pair of vertices u,v. There can be two shortest paths between u and v. The length of the cycle is Duv+ Dvu. This then is enough to compote the minimum of the Duv+Dvu for any given pair of vertices u and v.
Could I write this in a way to make it at most O(nm log n) (where n is the number of vertices and m is the number of edges) instead of O|V|3|?

Yes, in fact this problem can be solved in O(nm) according to a conference paper by Orlin and Sedeño-Noda (2017), titled An O(nm) time algorithm for finding the min length directed cycle in a graph:
In this paper, we introduce an O(nm) time algorithm to determine the minimum length directed cycle (also called the "minimum weight directed cycle") in a directed network with n nodes and m arcs and with no negative length directed cycles.

Related

How to Find shortest paths with k negative weighted edges?

The problem is to find shortest paths from a start vertice to all other vertices in a directed graph.
But the graph will have m positive weighted edges and k negative weighted edges, and it's guaranteed that negative weighted edges will be not in a cycle. In other words, there is no negative weighted cycle in this graph.
I tried to directly use Bellman-Ford and SPFA to solve this question but does there exists a faster way to do this?
If k is large enough, you should probably just run Bellman–Ford and call it a day.
If k is small, you can borrow the re-weighting trick from Johnson’s algorithm, but with a faster initialization than just running Bellman–Ford. Recall that Johnson computes a potential π(v) for each vertex and adjusts the cost of each arc vw from c(vw) to c′(vw) = c(vw) − π(v) + π(w), choosing π so that c′ is nowhere negative. The shortest path between s and t is the same with respect to c as with respect to c′,
Suppose that the input graph G has exactly one negative arc, let’s say c(xy) < 0. Use Dijkstra’s algorithm to compute distances in G − xy from y to all other vertices. Then define π(v) = distance(y, v). The correctness proof follows the proof of Johnson’s algorithm; the arc xy can’t be part of a shortest path from y because there are no negative cycles, so Dijkstra on G - xy in fact computes a shortest path tree for G.
For general k, we can do this recursively. If k = 0, run Dijkstra. Otherwise, remove a negative arc and compute shortest paths recursively instead of with Dijkstra. Once we have good values for π, run Dijkstra one more time, from the given start vertex.
The overall running time is O((k + 1) (m + n log n)) with Fibonacci heaps.

Backtrack after running Johnson algorithm

I have a question which I was asked in some past exams at my school and I can't find an answer to it.
Is it possible knowing the final matrix after running the Johnson Algorithm on a graph, to know if it previously had negative cycles or not? Why?
Johnson Algorithm
Johnson's Algorithm is a technique that is able to compute shortest paths on graphs. Which is able to handle negative weights on edges, as long as there does not exist a cycle with negative weight.
The algorithm consists of (from Wikipedia):
First, a new node q is added to the graph, connected by zero-weight edges to each of the other nodes.
Second, the Bellman–Ford algorithm is used, starting from the new vertex q, to find for each vertex v the minimum weight h(v) of a path from q to v. If this step detects a negative cycle, the algorithm is terminated.
Next the edges of the original graph are reweighted using the values computed by the Bellman–Ford algorithm: an edge from u to v, having length w(u, v), is given the new length w(u,v) + h(u) − h(v).
Finally, q is removed, and Dijkstra's algorithm is used to find the shortest paths from each node s to every other vertex in the reweighted graph.
If I understood your question correctly, which should have been as follows:
Is it possible knowing the final pair-wise distances matrix after running the Johnson Algorithm on a graph, to know if it originally had any negative-weight edges or not? Why?
As others commented here, we must first assume the graph has no negative weight cycles, since otherwise the Johnson algorithm halts and returns False (due to the internal Bellman-Form detection of negative weight cycles).
The answer then is that if any negative weight edge e = (u, v) exists in the graph, then the shortest weighted distance between u --> v cannot be > 0 (since at the worst case you can travel the negative edge e between those vertices).
Therefore, at least one of the edges had negative weight in the original graph iff any value in the final pair-wise distances is < 0
If the question is supposed to be interpreted as:
Is it possible, knowing the updated non-negative edge weights after running the Johnson Algorithm on a graph, to know if it originally had any negative-weight edges or not? Why?
Then no, you can't tell.
Running the Johnson algorithm on a graph that has only non-negative edge weights will leave the weights unchanged. This is because all of the shortest distances q -> v will be 0. Therefore, given the edge weights after running Johnson, the initial weights could have been exactly the same.

Special Case for MST algorithm in linear time

Let G = (V, E) be a weighted undirected connected graph, where all the
edge weights are distinct. Let T denote the minimum spanning tree.
Suppose that G has m ≤ n + 157 edges. For this special case, give an MST
algorithm that runs in O(n) time beating Kruskals and Prims algorithm.
Any hints?
First verify that the graph is connected.
Then repeat until the graph is a tree (# edges = n-1):
Find a cycle using DFS. There must be one since #edges >= n
Remove the longest edge in the cycle. It cannot be part of the MST.
When done you are left with the MST.
Even though this can take O(n) time per iteration, there will be at most 158 iterations, so that is still O(n) all together.

How to find longest increasing subsequence among all simple paths of an unweighted general graph?

Let G = (V, E) be an unweighted general graph in which every vertex v has a weight w(v).
An increasing subsequence of a simple path p in G is a sequence of vertices of p in which the weights of all vertices along this sequence increase. The simple paths can be closed paths.
A longest increasing subsequence (LIS) of a simple path p is an increasing subsequence of p such that has maximum number of vertices.
The question is that, how to find a longest increasing subsequence among all simple paths of G?
Note that the graph is undirected, therefore it is not a directed acyclic graph (DAG).
Here's a very fast algorithm for solving this problem. The longest increasing subsequence in the graph is a subsequence of a path in the graph, and each path must belong purely to a single connected component. So if we can solve this problem on connected components, we can solve it for the overall graph by finding the best solution across all connected components.
Next, think about the case where you're solving this problem for a connected graph G. In that case, the longest increasing subsequence you could find would be formed by sorting the nodes by their weight, then traversing from the lowest-weight node to the second, then to the third, then to the fourth, etc. If there are any ties or duplicates, you can just skip them. In other words, you can solve this problem by
Sorting all the nodes by weight,
Discarding all but one node of each weight, and
Forming an LIS by visiting each node in sequence.
This leads to a very fast algorithm for the overall problem. In time O(m + n), find all connected components. For each connected component, use the preceding algorithm in time O(Sort(n)), where Sort(n) is the time required to sort n elements (which could be Θ(n log n) if you use heapsort, Θ(n + U) for bucket sort, Θ(n lg U) for radix sort, etc.). Then, return the longest sequence you find.
Overall, the runtime is O(m + n + &Sort(n)), which beats my previous approach and should be a lot easier to code up.
I had originally posted this answer, which I'll leave up because I think it's interesting:
Imagine that you pick a simple path out of the graph G and look at the longest increasing subsequence of that path. Although the path walks all over the graph and might have lots of intermediary nodes, the longest increasing subsequence of that path really only cares about
the first node on the path that's also a part of the LIS, and
from that point, the next-largest value in the path.
As a result, we can think about forming an LIS like this. Start at any node in the graph. Now, travel to any node in the graph that (1) has a higher value than the current node and (2) is reachable from the current node, then repeat this process as many times as desired. The goal is to do so in a way that gives the longest possible sequence of increasing values.
We can model this process as finding a longest path in a DAG. Each node in the DAG represents a node in the original graph G, and there's an edge from a node u to a node v if
there's a path from u to v in G, and
w(u) < w(v).
This is a DAG because of that second condition, even though the original graph isn't a DAG.
So we can solve this overall problem in a two-step process. First, build the DAG described above. To do so:
Find the connected components of the original graph G and label each node with its connected component number. Time: O(m + n).
For each node u in G, construct a corresponding node u' in a new DAG D. Time: O(n).
For each node u in G, and for each node v in G that's in the same SCC as u, if w(u) < w(v), add an edge from u' to v'. Time: Θ(n2) in the worst-case, Θ(n) in the best case.
Find the longest path in D. This path corresponds to the longest increasing subsequence of any simple path in G. Time: O(m + n).
Overall runtime: Θ(n2) in the worst-case, Θ(m + n) in the best-case.

Minimum path in an undirected graph with locked and unlocked edges

Given an undirected graph with positive weights, there are 2 kinds of edges: locked edges and unlocked edges. Determination if a given edge is either locked or unlocked edge takes O(1).
For given two vertices s , t and a positive number k = O(1), how can I find the shortest path between s and t which contains at most k locked edges?
For given two vertices s , t and a positive number k = O(1), how can I find the shortest path between s and t which contains exactly k locked edges?
I'm not sure how can I run Dijkstra algorithm on this graph to find the shortest path between the given vertices, and how can I transform the undirected graph, into an directed one.
You can solve both of your problems by taking k copies of the graph, say G_0, ..., G_k, and modifying each graph so that a locked edge vw in G_i turns into an edge from u in G_i to v in G_{i+1} and from v in G_i to u in G_{i+1}. Then you can do single-source shortest paths from your root in G_0. The second query is solved by reading off the distance to the target in G_k, while the first is solved by reading off the minimum distance in any G_i to the target.

Resources