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 treevoid 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;}