给定一棵树,其中N个顶点编号为[0, n – 1] 、 K个顶点和距离D ,任务是查找是否存在从根到某个顶点的路径,使得K个顶点中的每个顶点都属于该路径或至多与路径的距离为D。
例子:
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.
方法:
- 对于每个顶点,存储它们各自的父级和深度。
- 从给定的K个顶点中选择最深的顶点
- 继续用其父D次替换除根和最深顶点之外的K个顶点
- 如果当前的K个顶点集可以形成一条连续路径,则答案为Yes或No。
下面的代码是上述方法的实现:
C++
// C++ implementation of above approach
#include
using namespace std;
// Class to represent the Tree
class Tree {
int T;
// Stores the timing of traversals
vector parent;
// Stores the parent of each vertex
vector depth;
// Stores the depth of each vertex
vector tin;
// Stores the time to reach
// every vertex
vector tout;
// Stores the time of leaving
// every vertex after DFS calls
// from its children
vector > edges;
// Store the edges
public:
// Constructor
Tree(int n)
{
T = 0;
parent = depth = vector(n);
tin = tout = vector(n);
edges = vector >(n);
}
// Adding edges
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)
{
// Store the time to reach vertex v
tin[v] = T++;
// Store the parent of vertex v
parent[v] = p;
// Store the depth of vertex v
depth[v] = d;
// Run DFS for all its children of v
for (auto i : edges[v]) {
if (i == p)
continue;
dfs(i, v, d + 1);
}
// Store the leaving time
// of vertex v
tout[v] = T++;
}
// Checks and returns whether vertex
// v is parent of vertex u or not
bool checkTiming(int v, int u)
{
if (tin[v] <= tin[u]
&& tout[u] <= tout[v])
return true;
return false;
}
// Checks and returns if the path exists
void pathExistence(vector k, int d)
{
int deepest_vertex = k[0];
// Find the deepest vertex among the
// given K vertices
for (int i = 0; i < k.size(); i++) {
if (depth[k[i]] > depth[deepest_vertex])
deepest_vertex = k[i];
}
// Replace each of the K vertices
// except for the root and the
// deepest vertex
for (int i = 0; i < k.size(); i++) {
if (k[i] == deepest_vertex)
continue;
int count = d;
while (count > 0) {
// Stop when root
// has been reached
if (parent[k[i]] == -1)
break;
k[i] = parent[k[i]];
count--;
}
}
bool ans = true;
// Check if each of the K-1 vertices
// are a parent of the deepest vertex
for (auto i : k)
ans &= checkTiming(i, deepest_vertex);
if (ans)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
};
// Driver Code
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 k = { 2, 6, 8, 5 };
int d = 2;
t.pathExistence(k, d);
return 0;
}
Java
// Java implementation of above approach
import java.util.*;
import java.lang.*;
class GFG{
static int T;
// Stores the timing of traversals
static int[] parent;
// Stores the parent of each vertex
static int[] depth;
// Stores the depth of each vertex
static int[] tin;
// Stores the time to reach
// every vertex
static int[] tout;
// Stores the time of leaving
// every vertex after DFS calls
// from its children
static ArrayList> edges;
// Adding 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)
{
// Store the time to reach vertex v
tin[v] = T++;
// Store the parent of vertex v
parent[v] = p;
// Store the depth of vertex v
depth[v] = d;
// Run DFS for all its children of v
for(Integer i : edges.get(v))
{
if (i == p)
continue;
dfs(i, v, d + 1);
}
// Store the leaving time
// of vertex v
tout[v] = T++;
}
// Checks and returns whether vertex
// v is parent of vertex u or not
static boolean checkTiming(int v, int u)
{
if (tin[v] <= tin[u] &&
tout[u] <= tout[v])
return true;
return false;
}
// Checks and returns if the path exists
static void pathExistence(int[] k, int d)
{
int deepest_vertex = k[0];
// Find the deepest vertex among the
// given K vertices
for(int i = 0; i < k.length; i++)
{
if (depth[k[i]] > depth[deepest_vertex])
deepest_vertex = k[i];
}
// Replace each of the K vertices
// except for the root and the
// deepest vertex
for(int i = 0; i < k.length; i++)
{
if (k[i] == deepest_vertex)
continue;
int count = d;
while (count > 0)
{
// Stop when root
// has been reached
if (parent[k[i]] == -1)
break;
k[i] = parent[k[i]];
count--;
}
}
boolean ans = true;
// Check if each of the K-1 vertices
// are a parent of the deepest vertex
for(int i : k)
ans &= checkTiming(i, deepest_vertex);
if (ans)
System.out.println("Yes");
else
System.out.println("No");
}
// Driver code
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);
}
}
// This code is contributed by offbeat
输出:
Yes
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live