/* Find neatest (lowest) common ancestor of two given nodes X1 and X2
input format : an integer T denoting number of test cases followed by 3 T Lines as each test case will
contain 3 lines
first line N
second line elements
where the no at index i is the parent of node i . The parent of root is -1
third line X1 and X2
output:
for each test case out put a single line that has the neatest (lowest) common ancestor of two given nodes X1 and X2
*/
#include<stdio.h>
#include <queue>
#include <vector>
using namespace std;
# define MAX_Q_SIZE 25
// A tree node
struct Node
{
int key;
struct Node *left, *right;
};
// Utility function to create new Node
Node *newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
// Creates a node with key as 'i'. If i is root, then it changes
// root. If parent of i is not created, then it creates parent first
void createNode(int parent[], int i, Node *created[], Node **root)
{
// If this node is already created
if (created[i] != NULL)
return;
// Create a new node and set created[i]
created[i] = newNode(i);
// If 'i' is root, change root pointer and return
if (parent[i] == -1)
{
*root = created[i];
return;
}
// If parent is not created, then create parent first
if (created[parent[i]] == NULL)
createNode(parent, parent[i], created, root);
// Find parent pointer
Node *p = created[parent[i]];
// If this is first child of parent
if (p->left == NULL)
p->left = created[i];
else // If second child
p->right = created[i];
}
// Creates tree from parent[0..n-1] and returns root of the created tree
Node *createTree(int parent[], int n)
{
// Create an array created[] to keep track
// of created nodes, initialize all entries
// as NULL
Node *created[n];
for (int i=0; i<n; i++)
created[i] = NULL;
Node *root = NULL;
for (int i=0; i<n; i++)
createNode(parent, i, created, &root);
return root;
}
// Finds the path from root node to given root of the tree, Stores the
// path in a vector path[], returns true if path exists otherwise false
bool findPath(Node *root, vector<int> &path, int k)
{
// base case
if (root == NULL) return false;
// Store this node in path vector. The node will be removed if
// not in path from root to k
path.push_back(root->key);
// See if the k is same as root's key
if (root->key == k)
return true;
// Check if k is found in left or right sub-tree
if ( (root->left && findPath(root->left, path, k)) ||
(root->right && findPath(root->right, path, k)) )
return true;
// If not present in subtree rooted with root, remove root from
// path[] and return false
path.pop_back();
return false;
}
// Returns LCA if node n1, n2 are present in the given binary tree,
// otherwise return -1
int findLCA(Node *root, int n1, int n2)
{
// to store paths to n1 and n2 from the root
vector<int> path1, path2;
// Find paths from root to n1 and root to n1. If either n1 or n2
// is not present, return -1
if ( !findPath(root, path1, n1) || !findPath(root, path2, n2))
return -1;
/* Compare the paths to get the first different value */
int i;
for (i = 0; i < path1.size() && i < path2.size() ; i++)
if (path1[i] != path2[i])
break;
return path1[i-1];
}
// Driver method
int main()
{
int x1,x2;
int k,T,n;
int result[100] ;
int parent[1000];
scanf("%d",&T);
k=T;
while(k>=1)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&parent[i]);
Node *root = createTree(parent, n);
scanf("%d%d",&x1,&x2);
result[k]=findLCA(root, x1, x2);
//printf("\nresult %d",result[k]);
k--;
}
for(int j=T;j>=1;j--)
printf("\n%d",result[j]);
}
input:
2
6
5 -1 1 1 5 2
0 3
7
-1 0 0 1 1 3 5
6 5
o/p
1
5
input format : an integer T denoting number of test cases followed by 3 T Lines as each test case will
contain 3 lines
first line N
second line elements
where the no at index i is the parent of node i . The parent of root is -1
third line X1 and X2
output:
for each test case out put a single line that has the neatest (lowest) common ancestor of two given nodes X1 and X2
*/
#include<stdio.h>
#include <queue>
#include <vector>
using namespace std;
# define MAX_Q_SIZE 25
// A tree node
struct Node
{
int key;
struct Node *left, *right;
};
// Utility function to create new Node
Node *newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
// Creates a node with key as 'i'. If i is root, then it changes
// root. If parent of i is not created, then it creates parent first
void createNode(int parent[], int i, Node *created[], Node **root)
{
// If this node is already created
if (created[i] != NULL)
return;
// Create a new node and set created[i]
created[i] = newNode(i);
// If 'i' is root, change root pointer and return
if (parent[i] == -1)
{
*root = created[i];
return;
}
// If parent is not created, then create parent first
if (created[parent[i]] == NULL)
createNode(parent, parent[i], created, root);
// Find parent pointer
Node *p = created[parent[i]];
// If this is first child of parent
if (p->left == NULL)
p->left = created[i];
else // If second child
p->right = created[i];
}
// Creates tree from parent[0..n-1] and returns root of the created tree
Node *createTree(int parent[], int n)
{
// Create an array created[] to keep track
// of created nodes, initialize all entries
// as NULL
Node *created[n];
for (int i=0; i<n; i++)
created[i] = NULL;
Node *root = NULL;
for (int i=0; i<n; i++)
createNode(parent, i, created, &root);
return root;
}
// Finds the path from root node to given root of the tree, Stores the
// path in a vector path[], returns true if path exists otherwise false
bool findPath(Node *root, vector<int> &path, int k)
{
// base case
if (root == NULL) return false;
// Store this node in path vector. The node will be removed if
// not in path from root to k
path.push_back(root->key);
// See if the k is same as root's key
if (root->key == k)
return true;
// Check if k is found in left or right sub-tree
if ( (root->left && findPath(root->left, path, k)) ||
(root->right && findPath(root->right, path, k)) )
return true;
// If not present in subtree rooted with root, remove root from
// path[] and return false
path.pop_back();
return false;
}
// Returns LCA if node n1, n2 are present in the given binary tree,
// otherwise return -1
int findLCA(Node *root, int n1, int n2)
{
// to store paths to n1 and n2 from the root
vector<int> path1, path2;
// Find paths from root to n1 and root to n1. If either n1 or n2
// is not present, return -1
if ( !findPath(root, path1, n1) || !findPath(root, path2, n2))
return -1;
/* Compare the paths to get the first different value */
int i;
for (i = 0; i < path1.size() && i < path2.size() ; i++)
if (path1[i] != path2[i])
break;
return path1[i-1];
}
// Driver method
int main()
{
int x1,x2;
int k,T,n;
int result[100] ;
int parent[1000];
scanf("%d",&T);
k=T;
while(k>=1)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&parent[i]);
Node *root = createTree(parent, n);
scanf("%d%d",&x1,&x2);
result[k]=findLCA(root, x1, x2);
//printf("\nresult %d",result[k]);
k--;
}
for(int j=T;j>=1;j--)
printf("\n%d",result[j]);
}
input:
2
6
5 -1 1 1 5 2
0 3
7
-1 0 0 1 1 3 5
6 5
o/p
1
5
No comments:
Post a Comment