Check if a path exists in a tree with K vertices present or are at most at a distance D
Last Updated :
29 Mar, 2023
Given a tree with N vertices numbered [0, n – 1], K vertices, and a distance D, the task is to find whether there is a path from the root to some vertex such that each of the K vertices belongs to the path or are at most at a distance D from the path.
Examples:
Input:
0
/ \
/ \
1 2
/ \ / \
/ \ / \
3 4 5 8
/ \
/ \
6 7
/
/
9
K = {6, 7, 8, 5}, D = 1
Output: YES
Explanation:
The path ( 0 - 2 - 5 - 7 )
satisfies the condition. Vertices 5
and 7 are a part of the path.
Vertex 6 is the child of vertex
5 and 8 is the child of 2.
Input:
0
/ \
/ \
1 2
/ \ / \
/ \ / \
3 4 5 8
\ / \
\ / \
10 6 7
/
/
9
K = {10, 9, 8, 5}, D = 2
Output: NO
Explanation:
No such path exists that satisfies the condition.
Approach:
- For every vertex, store their respective parent and depth.
- Select the deepest vertex from the given K vertices
- Keep replacing the K vertices except the root and the deepest vertex by its parent D times
- If the current set of K vertices can form a continuous path, then the answer is Yes or No otherwise.
Below code is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Tree {
int T;
vector< int > parent;
vector< int > depth;
vector< int > tin;
vector< int > tout;
vector<vector< int > > edges;
public :
Tree( int n)
{
T = 0;
parent = depth = vector< int >(n);
tin = tout = vector< int >(n);
edges = vector<vector< int > >(n);
}
void addEdge( int u, int v)
{
edges[u].push_back(v);
edges[v].push_back(u);
}
void dfs( int v, int p = -1, int d = 0)
{
tin[v] = T++;
parent[v] = p;
depth[v] = d;
for ( auto i : edges[v]) {
if (i == p)
continue ;
dfs(i, v, d + 1);
}
tout[v] = T++;
}
bool checkTiming( int v, int u)
{
if (tin[v] <= tin[u]
&& tout[u] <= tout[v])
return true ;
return false ;
}
void pathExistence(vector< int > k, int d)
{
int deepest_vertex = k[0];
for ( int i = 0; i < k.size(); i++) {
if (depth[k[i]] > depth[deepest_vertex])
deepest_vertex = k[i];
}
for ( int i = 0; i < k.size(); i++) {
if (k[i] == deepest_vertex)
continue ;
int count = d;
while (count > 0) {
if (parent[k[i]] == -1)
break ;
k[i] = parent[k[i]];
count--;
}
}
bool ans = true ;
for ( auto i : k)
ans &= checkTiming(i, deepest_vertex);
if (ans)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
};
int main()
{
Tree t(11);
t.addEdge(0, 1);
t.addEdge(0, 2);
t.addEdge(1, 3);
t.addEdge(1, 4);
t.addEdge(2, 5);
t.addEdge(2, 8);
t.addEdge(5, 6);
t.addEdge(4, 10);
t.addEdge(3, 7);
t.addEdge(3, 9);
t.dfs(0);
vector< int > k = { 2, 6, 8, 5 };
int d = 2;
t.pathExistence(k, d);
return 0;
}
|
Java
import java.util.*;
import java.lang.*;
class GFG{
static int T;
static int [] parent;
static int [] depth;
static int [] tin;
static int [] tout;
static ArrayList<ArrayList<Integer>> edges;
static void addEdge( int u, int v)
{
edges.get(u).add(v);
edges.get(v).add(u);
}
static void dfs( int v, int p, int d)
{
tin[v] = T++;
parent[v] = p;
depth[v] = d;
for (Integer i : edges.get(v))
{
if (i == p)
continue ;
dfs(i, v, d + 1 );
}
tout[v] = T++;
}
static boolean checkTiming( int v, int u)
{
if (tin[v] <= tin[u] &&
tout[u] <= tout[v])
return true ;
return false ;
}
static void pathExistence( int [] k, int d)
{
int deepest_vertex = k[ 0 ];
for ( int i = 0 ; i < k.length; i++)
{
if (depth[k[i]] > depth[deepest_vertex])
deepest_vertex = k[i];
}
for ( int i = 0 ; i < k.length; i++)
{
if (k[i] == deepest_vertex)
continue ;
int count = d;
while (count > 0 )
{
if (parent[k[i]] == - 1 )
break ;
k[i] = parent[k[i]];
count--;
}
}
boolean ans = true ;
for ( int i : k)
ans &= checkTiming(i, deepest_vertex);
if (ans)
System.out.println( "Yes" );
else
System.out.println( "No" );
}
public static void main(String[] args)
{
int n = 11 ;
T = 0 ;
parent = new int [n];
depth = new int [n];
tin = new int [n];
tout = new int [n];
edges = new ArrayList<>();
for ( int i = 0 ; i < n; i++)
edges.add( new ArrayList<>());
addEdge( 0 , 1 );
addEdge( 0 , 2 );
addEdge( 1 , 3 );
addEdge( 1 , 4 );
addEdge( 2 , 5 );
addEdge( 2 , 8 );
addEdge( 5 , 6 );
addEdge( 4 , 10 );
addEdge( 3 , 7 );
addEdge( 3 , 9 );
dfs( 0 , - 1 , 0 );
int [] k = { 2 , 6 , 8 , 5 };
int d = 2 ;
pathExistence(k, d);
}
}
|
Python3
T = 0
n = 11
parent = n * [ 0 ]
depth = n * [ 0 ]
tin = n * [ 0 ]
tout = n * [ 0 ]
edges = []
for i in range (n):
edges.append([])
def addEdge(u, v):
edges[u].append(v)
edges[v].append(u)
def dfs(v, p, d):
global T
T + = 1
tin[v] = T
parent[v] = p
depth[v] = d
for i in edges[v]:
if (i = = p):
continue
dfs(i, v, d + 1 )
T + = 1
tout[v] = T
def checkTiming(v, u):
if (tin[v] < = tin[u] and tout[u] < = tout[v]):
return True
return False
def pathExistence(k, d):
deepest_vertex = k[ 0 ]
for i in range ( len (k)):
if (depth[k[i]] > depth[deepest_vertex]):
deepest_vertex = k[i]
for i in range ( len (k)):
if (k[i] = = deepest_vertex):
continue
count = d
while (count > 0 ):
if (parent[k[i]] = = - 1 ):
break
k[i] = parent[k[i]]
count - = 1
ans = True
for i in k:
ans & = checkTiming(i, deepest_vertex)
if ans:
print ( "Yes" )
else :
print ( "No" )
addEdge( 0 , 1 )
addEdge( 0 , 2 )
addEdge( 1 , 3 )
addEdge( 1 , 4 )
addEdge( 2 , 5 )
addEdge( 2 , 8 )
addEdge( 5 , 6 )
addEdge( 4 , 10 )
addEdge( 3 , 7 )
addEdge( 3 , 9 )
dfs( 0 , - 1 , 0 )
k = [ 2 , 6 , 8 , 5 ]
d = 2
pathExistence(k, d)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int T;
static int [] parent;
static int [] depth;
static int [] tin;
static int [] tout;
static List<List< int >> edges;
static void addEdge( int u, int v)
{
edges[u].Add(v);
edges[v].Add(u);
}
static void dfs( int v, int p, int d)
{
tin[v] = T++;
parent[v] = p;
depth[v] = d;
foreach ( int i in edges[v])
{
if (i == p)
continue ;
dfs(i, v, d + 1);
}
tout[v] = T++;
}
static bool checkTiming( int v, int u)
{
if (tin[v] <= tin[u] && tout[u] <= tout[v])
return true ;
return false ;
}
static void pathExistence( int [] k, int d)
{
int deepest_vertex = k[0];
for ( int i = 0; i < k.Length; i++)
{
if (depth[k[i]] > depth[deepest_vertex])
deepest_vertex = k[i];
}
for ( int i = 0; i < k.Length; i++)
{
if (k[i] == deepest_vertex)
continue ;
int count = d;
while (count > 0)
{
if (parent[k[i]] == -1)
break ;
k[i] = parent[k[i]];
count--;
}
}
bool ans = true ;
foreach ( int i in k)
ans &= checkTiming(i, deepest_vertex);
if (ans)
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
static void Main() {
int n = 11;
T = 0;
parent = new int [n];
depth = new int [n];
tin = new int [n];
tout = new int [n];
edges = new List<List< int >>();
for ( int i = 0; i < n; i++)
edges.Add( new List< int >());
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(1, 4);
addEdge(2, 5);
addEdge(2, 8);
addEdge(5, 6);
addEdge(4, 10);
addEdge(3, 7);
addEdge(3, 9);
dfs(0, -1, 0);
int [] k = { 2, 6, 8, 5 };
int d = 2;
pathExistence(k, d);
}
}
|
Javascript
<script>
let T;
let parent;
let depth;
let tin;
let tout;
let edges;
function addEdge(u, v)
{
edges[u].push(v);
edges[v].push(u);
}
function dfs(v, p, d)
{
tin[v] = T++;
parent[v] = p;
depth[v] = d;
for (let i = 0; i < edges[v].length; i++)
{
if (edges[v][i] == p)
continue ;
dfs(edges[v][i], v, d + 1);
}
tout[v] = T++;
}
function checkTiming(v, u)
{
if (tin[v] <= tin[u] &&
tout[u] <= tout[v])
return true ;
return false ;
}
function pathExistence(k, d)
{
let deepest_vertex = k[0];
for (let i = 0; i < k.length; i++)
{
if (depth[k[i]] > depth[deepest_vertex])
deepest_vertex = k[i];
}
for (let i = 0; i < k.length; i++)
{
if (k[i] == deepest_vertex)
continue ;
let count = d;
while (count > 0)
{
if (parent[k[i]] == -1)
break ;
k[i] = parent[k[i]];
count--;
}
}
let ans = true ;
for (let i = 0; i < k.length; i++)
ans &= checkTiming(k[i], deepest_vertex);
if (ans)
document.write( "Yes" );
else
document.write( "No" );
}
let n = 11;
T = 0;
parent = new Array(n);
depth = new Array(n);
tin = new Array(n);
tout = new Array(n);
edges = [];
for (let i = 0; i < n; i++)
edges.push([]);
addEdge(0, 1);
addEdge(0, 2);
addEdge(1, 3);
addEdge(1, 4);
addEdge(2, 5);
addEdge(2, 8);
addEdge(5, 6);
addEdge(4, 10);
addEdge(3, 7);
addEdge(3, 9);
dfs(0, -1, 0);
let k = [ 2, 6, 8, 5 ];
let d = 2;
pathExistence(k, d);
</script>
|
Time Complexity: O(N+K*D) where N is the number of vertices in the tree, K is the number of given vertices, and D is the maximum distance that needs to be traversed from each given vertex.
Space Complexity: O(N), which is used to store the various arrays used in the DFS traversal of the tree.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...