Algorithm for DAG with weighted vertices - algorithm

Let G = (V,E) be a DAG (directed acyclic graph). Each vertex v has a weight w(v) assigned to it. Given a vertex u, let f(u) = max{w(v) where v can reach u}. So, in other words, f(u) is the maximum weight among the weights of all vertices that can reach u. The goal is to write a linear time algorithm that computes f(u) for every vertex u in G.
For example, let this be the input graph:
Then the algorithm should compute the following:
f(A) = 5
f(B) = 12
f(C) = 15
f(D) = 12
f(E) = 12
Accomplishing this in O(n(n+m)) time is straightforward, but how can this be done in O(n+m) time?

Do a topological sort, then go through the nodes in this order and assign each node the max of the weight of itself and the f of the immediate predecessors (i.e. nodes that have an edge leading to the current node).

Related

Vertex Cover of a Tree Linear or Polynomial Time?

I have the following algorithm to find the minimum vertex cover of a tree. That is a minimal sized set S of vertices such that for every edge (v,u) in G either v is in S or u is in S.
I have been told the algorithm has linear time complexity, however I don't understand how this is the case, since isn't the number of edges incident to u of the order O(n) and so the complexity would be O(n^2)?
Let T = <V, E> be a Tree. That is, the vertex set is V, the edge set is E. Also suppose the cover set = C. The algorithm can be described as follows:
while V != [] do
Identify a leaf vertex v
Locate u = parent(v), the parent vertex of v.
Add u to C
Remove all the edges incident to u
return C.
In a tree, |E| = |V| - 1, so there are O(n) edges to deal with in total.

Find the N highest cost vertices that has a path to S, where S is a vertex in an undirected Graph G

I would like to know, what would be the most efficient way (w.r.t., Space and Time) to solve the following problem:
Given an undirected Graph G = (V, E), a positive number N and a vertex S in V. Assume that every vertex in V has a cost value. Find the N highest cost vertices that is connected to S.
For example:
G = (V, E)
V = {v1, v2, v3, v4},
E = {(v1, v2),
(v1, v3),
(v2, v4),
(v3, v4)}
v1 cost = 1
v2 cost = 2
v3 cost = 3
v4 cost = 4
N = 2, S = v1
result: {v3, v4}
This problem can be solved easily by the graph traversal algorithm (e.g., BFS or DFS). To find the vertices connected to S, we can run either BFS or DFS starting from S. As the space and time complexity of BFS and DFS is same (i.e., time complexity: O(V+E), space complexity: O(E)), here I am going to show the pseudocode using DFS:
Parameter Definition:
* G -> Graph
* S -> Starting node
* N -> Number of connected (highest cost) vertices to find
* Cost -> Array of size V, contains the vertex cost value
procedure DFS-traversal(G,S,N,Cost):
let St be a stack
let Q be a min-priority-queue contains <cost, vertex-id>
let discovered is an array (of size V) to mark already visited vertices
St.push(S)
// Comment: if you do not want to consider the case "S is connected to S"
// then, you can consider commenting the following line
Q.push(make-pair(S, Cost[S]))
label S as discovered
while St is not empty
v = St.pop()
for all edges from v to w in G.adjacentEdges(v) do
if w is not labeled as discovered:
label w as discovered
St.push(w)
Q.push(make-pair(w, Cost[w]))
if Q.size() == N + 1:
Q.pop()
let ret is a N sized array
while Q is not empty:
ret.append(Q.top().second)
Q.pop()
Let's first describe the process first. Here, I run the iterative version of DFS to traverse the graph starting from S. During the traversal, I use a priority-queue to keep the N highest cost vertices that is reachable from S. Instead of the priority-queue, we can use a simple array (or even we can reuse the discovered array) to keep the record of the reachable vertices with cost.
Analysis of space-complexity:
To store the graph: O(E)
Priority-queue: O(N)
Stack: O(V)
For labeling discovered: O(V)
So, as O(E) is the dominating term here, we can consider O(E) as the overall space complexity.
Analysis of time-complexity:
DFS-traversal: O(V+E)
To track N highest cost vertices:
By maintaining priority-queue: O(V*logN)
Or alternatively using array: O(V*logV)
The overall time-complexity would be: O(V*logN + E) or O(V*logV + E)

Algorithm for finding weight of path with lowest weight in weighted directed graph

I am given a G=(V,E) directed graph, and all of its edges have weight of either "0" or "1".
I'm given a vertex named "A" in the graph, and for each v in V, i need to find the weight of the path from A to v which has the lowest weight in time O(V+E).
I have to use only BFS or DFS (although this is probably a BFS problem).
I though about making a new graph where vertices that have an edge of 0 between them are united and then run BFS on it, but that would ruin the graph direction (this would work if the graph was undirected or the weights were {2,1} and for an edge of 2 i would create a new vertex).
I would appreciate any help.
Thanks
I think it can be done with a combination of DFS and BFS.
In the original BFS for an unweighted graph, we have the invariant that the distance of nodes unexplored have a greater or equal distance to those nodes explored.
In our BFS, for each node we first do DFS through all 0 weighted edges, mark down the distance, and mark it as explored. Then we can continue the other nodes in our BFS.
Array Seen[] = false
Empty queue Q
E' = {(a, b) | (a, b) = 0 and (a, b) is of E}
DFS(V, E', u)
for each v is adjacent to u in E' // (u, v) has an edge weighted 0
if Seen[v] = false
v.dist = u.dist
DFS(V, E', v)
Seen[u] = true
Enqueue(Q, u)
BFS(V, E, source)
Enqueue(Q, source)
source.dist = 0
DFS(V, E', source)
while (Q is not empty)
u = Dequeue(Q)
for each v is adjacent to u in E
if Seen[v] = false
v.dist = u.dist + 1
Enqueue(Q, v)
Seen[u] = true
After running the BFS, it can give you all shortest distance from the node source. If you only want a shortest distance to a single node, simply terminate when you see the destination node. And yes, it meets the requirement of O(V+E) time complexity.
This problem can be modified to the problem of Single Source Shortest Path.
You just need to reverse all the edge directions and find the minimum distance of each vertex v from the vertex A.
It could be easily observed that if in the initial graph if we had a minimal path from some vertex v to A, after changing the edge directions we would have the same minimal path from A to v.
This could be simply done either by Dijkstra OR as the edges just have two values {0 and 1}, it could also be done by modified BFS (first go to vertexes with distance 0, then 1, then 2 and so on.).

Maximum weighted path between two vertices in a directed acyclic Graph

Love some guidance on this problem:
G is a directed acyclic graph. You want to move from vertex c to vertex z. Some edges reduce your profit and some increase your profit. How do you get from c to z while maximizing your profit. What is the time complexity?
Thanks!
The problem has an optimal substructure. To find the longest path from vertex c to vertex z, we first need to find the longest path from c to all the predecessors of z. Each problem of these is another smaller subproblem (longest path from c to a specific predecessor).
Lets denote the predecessors of z as u1,u2,...,uk and dist[z] to be the longest path from c to z then dist[z]=max(dist[ui]+w(ui,z))..
Here is an illustration with 3 predecessors omitting the edge set weights:
So to find the longest path to z we first need to find the longest path to its predecessors and take the maximum over (their values plus their edges weights to z).
This requires whenever we visit a vertex u, all of u's predecessors must have been analyzed and computed.
So the question is: for any vertex u, how to make sure that once we set dist[u], dist[u] will never be changed later on? Put it in another way: how to make sure that we have considered all paths from c to u before considering any edge originating at u?
Since the graph is acyclic, we can guarantee this condition by finding a topological sort over the graph. topological sort is like a chain of vertices where all edges point left to right. So if we are at vertex vi then we have considered all paths leading to vi and have the final value of dist[vi].
The time complexity: topological sort takes O(V+E). In the worst case where z is a leaf and all other vertices point to it, we will visit all the graph edges which gives O(V+E).
Let f(u) be the maximum profit you can get going from c to u in your DAG. Then you want to compute f(z). This can be easily computed in linear time using dynamic programming/topological sorting.
Initialize f(u) = -infinity for every u other than c, and f(c) = 0. Then, proceed computing the values of f in some topological order of your DAG. Thus, as the order is topological, for every incoming edge of the node being computed, the other endpoints are calculated, so just pick the maximum possible value for this node, i.e. f(u) = max(f(v) + cost(v, u)) for each incoming edge (v, u).
Its better to use Topological Sorting instead of Bellman Ford since its DAG.
Source:- http://www.utdallas.edu/~sizheng/CS4349.d/l-notes.d/L17.pdf
EDIT:-
G is a DAG with negative edges.
Some edges reduce your profit and some increase your profit
Edges - increase profit - positive value
Edges - decrease profit -
negative value
After TS, for each vertex U in TS order - relax each outgoing edge.
dist[] = {-INF, -INF, ….}
dist[c] = 0 // source
for every vertex u in topological order
if (u == z) break; // dest vertex
for every adjacent vertex v of u
if (dist[v] < (dist[u] + weight(u, v))) // < for longest path = max profit
dist[v] = dist[u] + weight(u, v)
ans = dist[z];

Finding the shortest path in a graph between 2 nodes that goes through a subset of nodes

I'm trying to find out an efficient way of finding the shortest path between 2 nodes in a graph with positive edge costs that goes trough a subset of nodes.
More formally:
Given a graph G = (U, V) where U is the set of all nodes in the graph and V is the set of all edges in the graph, a subset of U called U' and a cost function say:
f : UxU -> R+
f(x, y) = cost to travel from node x to node y if there exists an edge
between node x and node y or 0 otherwise,
I have to find the shortest path between a source node and a target node that goes trough all the nodes in U'.
The order in which I visit the nodes in U' doesn't matter and I am allowed to visit a node more than once.
My original idea was to make use of Roy-Floyd algorithm to generate the cost matrix.
Then, for each permutation of the nodes in U' I would be computing the cost between the source and the target like this: f(source_node, P1) + f(P1, P2) + ... + f(Pk, target) saving the configuration for the lowest cost and then reconstructing the path.
The complexity for this approach is O(n3 + k!) O(n3 + k*k!), where n is the number of nodes in the graph and k the number of nodes in the subset U', which is off limits since I'll have to deal with graphs with maximum n = 2000 nodes out of which maximum n - 2 nodes will be part of the U' subset.
This is a generalization of travelling salesman. If U' == U, you get exactly TSP.
You can use the O(n^2 * 2^n) TSP algorithm, where the exponential factor for full scale TSP (2^n) will reduce to k = |U'|, so you'd get O(n^2 * 2^k).
This has the DP solution to TSP.
http://www.lsi.upc.edu/~mjserna/docencia/algofib/P07/dynprog.pdf
Combine the source node s and target node t into a single node z, and define the node set U'' := U' union {z}, with the distances to and from z defined by f(z,x) := f(s,x) and f(x,z) := f(x,t) for all x in U \ {s, t}. Compute shortest paths between all nodes of U'' and let f'(x,y) be the shortest distances, or infinity when there is no appropriate path. Voila, you now have a travelling salesman problem on the complete directed graph with vertices U'' and edge weights f'.

Resources