Two nodes at the maximum distance in a binary tree - binary-tree

I am stuck up with a modified version of the problem ( Find two nodes located at a distance k in a binary tree).
I was trying to define the distance between two nodes and I believe that it is the minimum number of nodes needed to travel from node n1 to node n2 along the tree branches.
Well proceeding with this assumption, I arrived at a situation where I believe I need to know for each node if it is to the left or right of the root.
Case1 : If n1 and n2 are on different side then I climb to the root ( distance equals to depth of the node n1 - assuming n1 is on left) and then I run down to the right node n2 ( distance equals to the depth of n2). So the maximum distance between two nodes n1 , n2 is the sum of their depths if they are on different sides of the root.
Case 2 : If n1 and n2 are on the same side, I find an ancestor common to both in the tree hierarchy and repeat the same process considering the ancestor a root as I did in the case 1.
The minimum distance will be the sum of their depths from root - 2 times the depth of common ancestor.
Now, the problem with this is, I end up doing this for every pair of node bluntly. I can optimize it to not check a pair if I know a pair of node which are at a distance more than this but how?
Please suggest the rest of the solution.

Same problem as Diameter of a Binary Tree(see the bottom up approach) which is defined as the number of nodes on the longest path between two leaves in the tree. In your case you have to find out nodes as well.

Related

ET-tree in Henzinger and King (1995)

I'm having trouble understanding the following from the beginning of section 2.5 of Henzinger and King (FOCS 1995):
We encode an arbitrary tree T with n vertices using a sequence of 2n - 1 symbols, which is generated as follows: Root the tree at an arbitrary vertex.
Then traverse T in depth-first search order traversing each edge twice (once in each direction) and visiting every degree-d vertex d times, except for the root which is visited d + 1 times. Each time any vertex u is encountered, we call this an occurrence of the vertex. Let ET(T) be the sequence of node occurrences representing an arbitrary tree T.
For each spanning tree T(B) of a block B of H_i each occurrence of ET(T(B)) is stored in a node of a balanced binary search tree, called the ET(T(B))-tree. For each vertex u in T(B), we arbitrarily choose one occurrence to be the active occurrence of u.
With the active occurrence of each vertex v, we keep the (unordered) list of nontree edges in B which are incident to u, stored as a balanced binary tree. Each node in the ET-tree contains the number of nontree edges stored in its subtree.
Using this data structure for each level we can sample an edge of T_1 in time O(logn).
My questions follow some explanation of some terms.
From section 2.2,
A block is a maximal set of nodes that are biconnected.
H_i is a subgraph of G, whose dynamic biconnectivity (which is much of the topic of the paper) we wish to maintain. (More specifically, the edge set of G has been partitioned into l = log(|E(G)|) sets and each set induces a graph H_i for 1 <= i <= l.)
Here's my understanding. Pick some T(B) of H_i. The key of each active node in the corresponding ET tree is the number of "nontree edges in B [that] are incident to u". The value of each node is the appropriate list of edges.
Questions:
To finalise the ET tree, we have each node store the sum of the keys of all nodes in its subtree (including the node itself)?
The list for each node is not a balanced tree, right?
If only the active nodes matter, why create an ET-tree in the first place?
To sample an edge, we generate a number between 1 and |E(B))|. If the number is between 1 and |V(B)| - 1 then we're choosing some tree edge. Otherwise, we traverse the balanced tree and then select the appropriate edge from a list?

Sum of K connected nodes binary tree

I want to find maximum sum of K connected nodes in a binary tree. I thought of doing this through memorizing, but I'm stuck.
Think about how the problem breaks down. A connected subgraph of a binary tree is itself a tree. In particular, there is a root of the the subgraph, and the children of the root are also trees.
So, consider the following related problem. Given the binary tree and a particular node X, what is the maximum sum of a subtree rooted at X, where the subtree has N nodes?
If you could answer that question for N=1 through N=i, then you can answer the same question for N=i+1 by fixing the node X, choosing j nodes from X's left child, and i-j nodes from X's right child, for some choice of 0<=j<=i. This illustrates the "optimal subproblem" property required for dynamic programming.

relation between degrees of vertices and edge removal

I'm looking for help to prove the next question:
given an undirected tree with n vertices with each one's degree <= 3,
(1) prove that there exists an edge that if we remove we'll have two trees with number of vertices in each one - maximum (2*n/3).
(2) suggest a linear algorithm that finds such an edge in the above given tree
Choose an arbitrary root. Do a post order traversal to compute the size of each subtree. By descending from the root via children with subtrees at least as large as their siblings, find a subtree of size between (n-1)/3 inclusive and 2(n-1)/3 + 1 exclusive (the degree bound keeps the size from decreasing by more than minus one divided by two). Sever its parent edge.

weight sum for path between two nodes in a tree

You are given a Tree with n vertices. Every node has an integer weight associated with it.
There are a huge number of queries(~n^2) on the given tree.
for a query (A, B), where A, B are two vertices of the tree, you need to calculate sum of weights of the nodes on the unique path from A to B, including A and B.
I can do dfs/bfs for individual queries but that is going to take O(n^3) for ~n^2 possible queries..
can anyone suggest something better which takes less than O(n) per query?
thanks..
If the tree is not rooted, make any arbitrary node the root of the tree.
We'll denote weight of the node x with W[x] and sum of weights of all nodes from root to node x with C[x].
Now let's assume there's a query like, u, v:
We've to find the Lowest Common Ancestor of node u and v. Let's assume the LCA of u and v is P. so the result for query (u,v) will be C[u]-C[P]+C[v]-C[P]+W[P]
Isn't your problem very similar to Timus Online Judge 1471.Tree ?
The only difference is that nodes are weighted in your problem while edges are weighted in Ural 1471.Tree.
This is a typical LCA problem.
Make anyone of the nodes as the root of the tree(if necessary), then calculate the distance dist[i] of every other nodes to the root, which takes O(N) time using BFS/DFS.
Then for each query(A,B), find the LCA L of (A,B), then the distance between of (A,B) is
dist[A] + dist[B] - 2*dist[L].
However, in your problem, it may be necessary to convert the node weight to edge weight.
If you are not familiar with the LCA algorithm, here is a very good site that may help you.

find a tree, given the data on its leaves

let there be an undirected tree T, and let there be: T.leaves - all the leaves (each v such that d(v) = 1). we know: |T.leaves| and the distance between u and v for each u,v in T.leaves.
in other words: we have an undirected tree, and we know how many leaves it has, and the distance between every 2 leaves.
we need to find how many inside vertices (d(v)>1) are in the tree.
note: building the complete tree is impossible because if we have only 2 leaves but the distance between them is 2^30, it will take too long...
I tried to start from the shortest distance and count how many vertices are between them, and then adding the vertex closest to them, but for this I need some formula f(leaves_counted,next_leaf) but I could not manage to find that f...
any ideas?
Continued from discussion in comments. This is how to check a particular (compressed) edge to see if you can attach the new vertex n somewhere in the middle of it, without iterating over the distances.
Ok, so you need to find three numbers: l (the distance of the attach point from the left node of the edge in question), x (the distance of the new node from the attach point) and r (symmetrical to l.)
Obviously, for every node y in set L (the left part of the tree), its distance to A must differ from its distance to n by the same number (lets call it dl which must be equal l + x). If this is not the case, there is no solution for this particular edge. Same goes for nodes in R, with dr and r + x respectively.
If the above holds, then you have three equations:
l + x = dl
r + x = dr
r+l = dist(A,B)
Three equations, three numbers. If this has a solution then you have found the right edge.
At worst you need to iterate the above for every edge, but I think it can be optimized - the distance check on L and R might exclude one of the parts of the tree from further search. It might also be possible to somehow get the number of nodes without even constructing the tree.
if your binary tree has L leaves then it has L-1 internal vertices regardless of the shape of the tree.
You can easily prove this: start with the tree with only one node (root) node. Then take any leaf, and add two descendants to it, converting the leaf into an internal vertex and adding to leaves. This removes one leaf (the old node), and adds one internal node and two leaves, i.e. net is +1 internal node and +1 leaf. Because you start with one leaf and 0 internal nodes, you have always |leaves| = |internal nodes|+1 --- any tree shape can be produced by this process.
Here examples of all the two shapes of trees with 4 leaves (save for trivial left-right symmetries):
o o
o L o o
o L L L L L
L L
The number of internal vertices is always 3.

Resources