Related: LeetCode 543 - Diameter of a Binary Tree
http://www.geeksforgeeks.org/diameter-of-a-binary-tree/
http://www.spoj.com/problems/PT07Z/
https://sukeesh.wordpress.com/2015/06/21/spoj-pt07z-longest-path-in-a-tree/
http://duecodes.blogspot.com/2016/08/spoj-longest-path-in-tree-solution.html
http://www.cnblogs.com/moris/p/4337088.html
Longest path in an undirected tree
http://www.geeksforgeeks.org/longest-path-undirected-tree/
Given an undirected tree, we need to find the longest path of this tree where a path is defined as a sequence of nodes.
This problem is same as diameter of n-ary tree.
http://www.geeksforgeeks.org/diameter-of-a-binary-tree/
The diameter of a tree (sometimes called the width) is the number of nodes on the longest path between two leaves in the tree. The diagram below shows two trees each with diameter nine, the leaves that form the ends of a longest path are shaded (note that there is more than one path in each tree of length nine, but no path longer than nine nodes).
The diameter of a tree T is the largest of the following quantities:
* the diameter of T’s left subtree
* the diameter of T’s right subtree
* the longest path between leaves that goes through the root of T (this can be computed from the heights of the subtrees of T)
* the diameter of T’s right subtree
* the longest path between leaves that goes through the root of T (this can be computed from the heights of the subtrees of T)
Optimized implementation: The above implementation can be optimized by calculating the height in the same recursion rather than calling a height() separately. Thanks to Amar for suggesting this optimized version. This optimization reduces time complexity to O(n)
class
Height
{
int
h;
}
/* define height =0 globally and call diameterOpt(root,height)
from main */
int
diameterOpt(Node root, Height height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
Height lh =
new
Height(), rh =
new
Height();
if
(root ==
null
)
{
height.h =
0
;
return
0
;
/* diameter is also 0 */
}
/* ldiameter --> diameter of left subtree
rdiameter --> Diameter of right subtree */
/* Get the heights of left and right subtrees in lh and rh
And store the returned values in ldiameter and ldiameter */
lh.h++; rh.h++;
int
ldiameter = diameterOpt(root.left, lh);
int
rdiameter = diameterOpt(root.right, rh);
/* Height of current node is max of heights of left and
right subtrees plus 1*/
height.h = Math.max(lh.h, rh.h) +
1
;
return
Math.max(lh.h + rh.h +
1
, Math.max(ldiameter, rdiameter));
}
/* A wrapper over diameter(Node root) */
int
diameter()
{
Height height =
new
Height();
return
diameterOpt(root, height);
}
Time Complexity: O(n^2)
/* Method to calculate the diameter and return it to main */
int
diameter(Node root)
{
/* base case if tree is empty */
if
(root ==
null
)
return
0
;
/* get the height of left and right sub trees */
int
lheight = height(root.left);
int
rheight = height(root.right);
/* get the diameter of left and right subtrees */
int
ldiameter = diameter(root.left);
int
rdiameter = diameter(root.right);
/* Return max of following three
1) Diameter of left subtree
2) Diameter of right subtree
3) Height of left subtree + height of right subtree + 1 */
return
Math.max(lheight + rheight +
1
,
Math.max(ldiameter, rdiameter));
}
/* A wrapper over diameter(Node root) */
int
diameter()
{
return
diameter(root);
}
/*The function Compute the "height" of a tree. Height is the
number f nodes along the longest path from the root node
down to the farthest leaf node.*/
static
int
height(Node node)
{
/* base case tree is empty */
if
(node ==
null
)
return
0
;
/* If tree is not empty then height = 1 + max of left
height and right heights */
return
(
1
+ Math.max(height(node.left), height(node.right)));
}
http://www.spoj.com/problems/PT07Z/
You are given an unweighted, undirected tree. Write a program to output the length of the longest path (from one node to another) in that tree. The length of a path in this case is number of edges we traverse from source to destination.
Input
The first line of the input file contains one integer N --- number of nodes in the tree (0 < N <= 10000). Next N-1 lines contain N-1 edges of that tree --- Each line contains a pair (u, v) means there is an edge between node u and node v (1 <= u, v <= N).
Output
Print the length of the longest path on one line.
Example
Input: 3 1 2 2 3 Output: 2http://www.fitcoding.com/2014/09/29/find-longest-path-in-tree/
public static int findLongestPath(TreeNode root) { // longest path = max (h1 + h2 + 2, longestpath(left), longestpath(right); int[] treeInfo = longestPathHelper(root); return treeInfo[0]; } private static int[] longestPathHelper(TreeNode root) { int[] retVal = new int[2]; if (root == null) { //height and longest path are 0 retVal[0] = 0; retVal[1] = 0; } int[] leftInfo = longestPathHelper(root.getLeft()); int[] rightInfo = longestPathHelper(root.getRight()); retVal[0] = Math.max(leftInfo[1] + rightInfo[1] + 2, Math.max(leftInfo[0], rightInfo[0])); retVal[1] = Math.max(leftInfo[1], rightInfo[1]) + 1; return retVal; }
Given below code is for PTZ07Z spoj or Longest path in a tree spoj.
You can solve this using DFS of applying BFS twice.
For BFS twice
In first bfs you have to find maximum length of node from root then in second bfs consider that node as root and find maximum distance from that .That will be our answer.
1-> Using DFS.
1-> Using DFS.
1-> Using DFS.
#include <bits/stdc++.h> using namespace std; #define MAX 100009 bool check[MAX]={false}; int total=0; int dfs(vector<int> v[],int root) { int m,m1=-1,m2=-1; check[root]=1; for(int i=0;i<v[root].size();i++) { if(!check[v[root][i]]){ m = dfs(v,v[root][i]); if(m>=m1) { m2= m1; m1 = m; } else if(m>m2) m2=m; } } total = max(total , m1+m2+2); return (m1 + 1); } int main() { int n,a,b; cin>>n; vector<int> v[n+9]; for(int i=0;i<n-1;i++){ scanf("%d%d",&a,&b); v[a].push_back(b); v[b].push_back(a); } dfs(v,1); cout<<total<<endl; }
1-> Using Double BFS .
#include <bits/stdc++.h> using namespace std; #define MAXN 10000 vector < int > g[MAXN + 1]; int maxWt[MAXN + 1]; bool check[MAXN + 1]; void bfs(int n) { queue <pair<int, int> > q; q.push(make_pair(n, 0)); while (!q.empty()) { int root = q.front().first; int wt = q.front().second; check[root] = true; for(int i = 0; i<g[root].size(); i++) { if (!check[g[root][i]]) { q.push(make_pair(g[root][i], wt + 1)); } } maxWt[root] = wt; q.pop(); } } int main() { int n,a,b; cin>>n; vector<pair<int,int> > v[n+9]; for(int i=0;i<n-1;i++) { cin>>a>>b; g[a].push_back(b); g[b].push_back(a); } bfs(1); int maxRoot = 0; for(int i = 1; i<= n; i++) maxRoot = maxWt[maxRoot] < maxWt[i] ? i : maxRoot; memset(maxWt, 0, sizeof(maxWt)); memset(check, 0, sizeof(check)); bfs(maxRoot); maxRoot = 0; for(int i = 1; i<= n; i++) maxRoot = max(maxRoot, maxWt[i]); cout<<maxRoot<<endl; return 0; }
http://duecodes.blogspot.com/2016/08/spoj-longest-path-in-tree-solution.html
http://www.cnblogs.com/moris/p/4337088.html
Longest path in an undirected tree
http://www.geeksforgeeks.org/longest-path-undirected-tree/
Given an undirected tree, we need to find the longest path of this tree where a path is defined as a sequence of nodes.
This problem is same as diameter of n-ary tree.
In this post, an efficient solution is discussed. We can find longest path using two BFSs. The idea is based on the following fact: If we start BFS from any node x and find a node with the longest distance from x, it must be an end point of the longest path. It can be proved using contradiction. So our algorithm reduces to simple two BFSs. First BFS to find an end point of the longest path and second BFS from this end point to find the actual longest path.
As we can see in above diagram, if we start our BFS from node-0, the node at the farthest distance from it will be node-5, now if we start our BFS from node-5 the node at the farthest distance will be node-7, finally, path from node-5 to node-7 will constitute our longest path.
As we can see in above diagram, if we start our BFS from node-0, the node at the farthest distance from it will be node-5, now if we start our BFS from node-5 the node at the farthest distance will be node-7, finally, path from node-5 to node-7 will constitute our longest path.
pair<
int
,
int
> Graph::bfs(
int
u)
{
// mark all distance with -1
int
dis[V];
memset
(dis, -1,
sizeof
(dis));
queue<
int
> q;
q.push(u);
// distance of u from u will be 0
dis[u] = 0;
while
(!q.empty())
{
int
t = q.front(); q.pop();
// loop for all adjacent nodes of node-t
for
(
auto
it = adj[t].begin(); it != adj[t].end(); it++)
{
int
v = *it;
// push node into queue only if
// it is not visited already
if
(dis[v] == -1)
{
q.push(v);
// make distance of v, one more
// than distance of t
dis[v] = dis[t] + 1;
}
}
}
int
maxDis = 0;
int
nodeIdx;
// get farthest node distance and its index
for
(
int
i = 0; i < V; i++)
{
if
(dis[i] > maxDis)
{
maxDis = dis[i];
nodeIdx = i;
}
}
return
make_pair(nodeIdx, maxDis);
}
// method prints longest path of given tree
void
Graph::longestPathLength()
{
pair<
int
,
int
> t1, t2;
// first bfs to find one end point of
// longest path
t1 = bfs(0);
// second bfs to find actual longest path
t2 = bfs(t1.first);
cout <<
"Longest path is from "
<< t1.first <<
" to "
<< t2.first <<
" of length "
<< t2.second;
}