Tree and Graph on same set of vertices - algorithm

Suppose you are given an undirected graph G and a tree T on the same set of vertices.
We would like to know whether it is possible to have an adjacency list representation
of G (note that there are multiple options here as the adjacency list can arrange the
neighbours of a vertex in any order) such that running Breadth First Search on G with
this adjacency list will result in T being the BFS Tree. Give an efficient algorithm to
solve this problem.

If T is rooted, then all we have to do is initialize Bellman--Ford with the distances implicitly given by T, perform one relaxation round, and return true if and only if nothing changed.
If T is not rooted, then I guess we can try all possible roots, but it does feel as though there should be a linear-time algorithm.

Related

Finding a Spanning Tree Using other Spanning Trees of 𝐺=(𝑉,𝐸)

I am having trouble coming up with a polynomial time algorithm to solve the following problem:
Let 𝐺=(𝑉,𝐸) be an undirected and unweighted graph with 𝑛 vertices. Let 𝑇_1,𝑇_2,...,𝑇_𝑘 be 𝑘=𝑛−1 distinct spanning trees of 𝐺. Find a polynomial time algorithm that finds a spanning tree
𝑇=(𝑉,𝐸_𝑇) in 𝐺 that contains at least one edge from each spanning tree 𝑇_𝑖.
I would really appreciate any help on this!
Spanning trees have matroid structure. Therefore the following greedy algorithm works: starting with an empty forest, for each input spanning tree, extend the forest by any one tree edge that does not create a cycle. Correctness follows more or less directly from the augmentation property and the definition of independence.
Here is a basic solution.
//if the graph is given in input:
// If any bridge exists in the graph:
// return any spanning tree from the list of input spanning trees
while the size of result set is less than |V|-1:
for every tree in the list of spanning trees:
for every edge in the tree:
if edge is not a part of result set:
if adding this edge to the result set doesn't form a cycle:
add the edge to result set
break
if size of result set is V-1:
break
Size of list of spanning trees < |V|-1: while loop is required
Size of list of spanning trees > |V|-1: a proof would be required that "the result set returned by above algorithm includes at least one edge from all the remaining trees in the list of spanning trees". I'll try this proof at leisure.
If for the given graph |E| < 2*(|V|-1) or the size list of spanning trees < |V|, then the above algorithm definitely works.
An interesting case is when |E| >= 2*(|V|-1). As shown in the image below, for some input list of spanning trees L, say the set of green edges is the result set returned by the above algorithm. A spanning tree of Blue edges could be formed without using any of the green edges.
Just posted this answer so that it works as some basic ground work for people trying to answer this question. Otherwise, could be treated as brute force solution.

The usage of graph traversal algorithm

I am reading the materials related to graph in Data Structures and Algorithms in C++ 4e(By Adam Drozdek). In his implementation of Graph Breadth First Search, the psuedo code is like:
BFS():
for all vertices u
num(u) = 0
edges = null
i = 1
while there is a vertex v such that num(v) is 0
num(v)++
enqueue(v)
while queue is not empty
v = dequeue()
if num(u) is 0
num(u) = i++
enqueue(u)
attach edge(v,u) to edges
output edges
Basically, in the implementation of graph, we already keep a set of all vertices and a set of all edges. In BFS, the algorithm first enumerate every vertex not visited in this set to traverse the complete graph.
My question is:
since we already store all the vertex in a set, we can loop through the set to operate on a particular vertex without using BFS algorithm. Why do we need a graph traversal algorithm and what is main use?
There are many uses for BFS and DFS...
To give you an idea for BFS:
You have a graph representing a social network and want to make friend suggestions for a particular user. Then, you do a BFS. The closer the vertices (people), the better rank in the friends suggestion list. (If the number of users is large, it makes sense to stop at a distance of 3 and not do the BFS on the entire graph).
Solution space searching. Extremely useful when the solution space is infinite. (see Game Trees)
Shortest paths (if the edges have the same weight and there are no loops). Dijkstra adapted it to work for variable weights (see Dijkstra's algorithm).
For instance, typically DFS is implicitly used when a tree is traversed recursively.

Computing another graph with edges of exactly length l from an unweighted, undirected graph

What is a method of making another graph featuring vertices that can be only gotten to with an edge length of l from every vertex V in the original unweighted (assume edges of length 1) and undirected graph G=(V,E). I came up with a solution that just searches through each branch from each V using depth-first search on each vertex until I found all the vertices of path length l from each vertex. This gives a runtime of O(V^(l+1)) so of course, this is not the optimal solution. Can anyone help me find a better solution with a better asymptotic runtime?
You could use the Floyd-Warshall algorithm that uses a matrix representation (as #Hammar suggested) but finishes in O(V^3) regardless of l. Instead of l matrix exponentiations, you determine all distances by sequentially inserting nodes and determining the effect on the shortest paths.

minimum connected subgraph containing a given set of nodes

I have an unweighted, connected graph. I want to find a connected subgraph that definitely includes a certain set of nodes, and as few extras as possible. How could this be accomplished?
Just in case, I'll restate the question using more precise language. Let G(V,E) be an unweighted, undirected, connected graph. Let N be some subset of V. What's the best way to find the smallest connected subgraph G'(V',E') of G(V,E) such that N is a subset of V'?
Approximations are fine.
This is exactly the well-known NP-hard Steiner Tree problem. Without more details on what your instances look like, it's hard to give advice on an appropriate algorithm.
I can't think of an efficient algorithm to find the optimal solution, but assuming that your input graph is dense, the following might work well enough:
Convert your input graph G(V, E) to a weighted graph G'(N, D), where N is the subset of vertices you want to cover and D is distances (path lengths) between corresponding vertices in the original graph. This will "collapse" all vertices you don't need into edges.
Compute the minimum spanning tree for G'.
"Expand" the minimum spanning tree by the following procedure: for every edge d in the minimum spanning tree, take the corresponding path in graph G and add all vertices (including endpoints) on the path to the result set V' and all edges in the path to the result set E'.
This algorithm is easy to trip up to give suboptimal solutions. Example case: equilateral triangle where there are vertices at the corners, in midpoints of sides and in the middle of the triangle, and edges along the sides and from the corners to the middle of the triangle. To cover the corners it's enough to pick the single middle point of the triangle, but this algorithm might choose the sides. Nonetheless, if the graph is dense, it should work OK.
The easiest solutions will be the following:
a) based on mst:
- initially, all nodes of V are in V'
- build a minimum spanning tree of the graph G(V,E) - call it T.
- loop: for every leaf v in T that is not in N, delete v from V'.
- repeat loop until all leaves in T are in N.
b) another solution is the following - based on shortest paths tree.
- pick any node in N, call it v, let v be a root of a tree T = {v}.
- remove v from N.
loop:
1) select the shortest path from any node in T and any node in N. the shortest path p: {v, ... , u} where v is in T and u is in N.
2) every node in p is added to V'.
3) every node in p and in N is deleted from N.
--- repeat loop until N is empty.
At the beginning of the algorithm: compute all shortest paths in G using any known efficient algorithm.
Personally, I used this algorithm in one of my papers, but it is more suitable for distributed enviroments.
Let N be the set of nodes that we need to interconnect. We want to build a minimum connected dominating set of the graph G, and we want to give priority for nodes in N.
We give each node u a unique identifier id(u). We let w(u) = 0 if u is in N, otherwise w(1).
We create pair (w(u), id(u)) for each node u.
each node u builds a multiset relay node. That is, a set M(u) of 1-hop neigbhors such that each 2-hop neighbor is a neighbor to at least one node in M(u). [the minimum M(u), the better is the solution].
u is in V' if and only if:
u has the smallest pair (w(u), id(u)) among all its neighbors.
or u is selected in the M(v), where v is a 1-hop neighbor of u with the smallest (w(u),id(u)).
-- the trick when you execute this algorithm in a centralized manner is to be efficient in computing 2-hop neighbors. The best I could get from O(n^3) is to O(n^2.37) by matrix multiplication.
-- I really wish to know what is the approximation ration of this last solution.
I like this reference for heuristics of steiner tree:
The Steiner tree problem, Hwang Frank ; Richards Dana 1955- Winter Pawel 1952
You could try to do the following:
Creating a minimal vertex-cover for the desired nodes N.
Collapse these, possibly unconnected, sub-graphs into "large" nodes. That is, for each sub-graph, remove it from the graph, and replace it with a new node. Call this set of nodes N'.
Do a minimal vertex-cover of the nodes in N'.
"Unpack" the nodes in N'.
Not sure whether or not it gives you an approximation within some specific bound or so. You could perhaps even trick the algorithm to make some really stupid decisions.
As already pointed out, this is the Steiner tree problem in graphs. However, an important detail is that all edges should have weight 1. Because |V'| = |E'| + 1 for any Steiner tree (V',E'), this achieves exactly what you want.
For solving it, I would suggest the following Steiner tree solver (to be transparent: I am one of the developers):
https://scipjack.zib.de/
For graphs with a few thousand edges, you will usually get an optimal solution in less than 0.1 seconds.

Calculating total number of spanning trees containing a particular set of edges

I have tried the following approach:
First I do edge contraction for all the edges in the given set of edges to form a modified graph.
Then I calculate the total number of spanning trees, using the matrix tree theorem, from the modified graph.
I want to know if this method is correct and if there are some other better methods.
Let G be a graph, let e be an edge, and let G/e be the same graph with e contracted. Then,
Proposition: There is a bijection between the spanning trees of G that contain e, and the spanning trees of G/e.
This proposition is not hard to prove; you're better off understanding the proof yourself instead of just asking other people whether it's true. Obviously if you have a spanning T tree of G that contains e, then T/e is a spanning tree of G/e. The thing to think through is that you can also go backwards.
And, as Adam points out, you have to be careful to properly handle graphs with parallel edges and graphs with edges from a vertex to itself.
I don't know if it's correct or not, but you'll have to be careful of the fact that edge contraction can lead to parallel edges. You'll have to make sure that trees differing only by which parallel edge is used are counted as being distinct.

Resources