For each query given by the pair (k_i, v_i), perform a depth-first or breadth-first search starting from vertex v_i. During the traversal, only follow edges whose relevance is at least k_i.
Count the number of reachable vertices , excluding the starting vertex v_i. The value of is the answer to the query (k_i, v_i).
Example
Farmer John has established the following connections between videos:
Video and video have a relevance of ,
Video and video have a relevance of ,
Video and video have a relevance of .
Based on this data, we can compute the relevance between other pairs of videos:
Video and video : relevance = min(3, 2) = 2,
Video and video : relevance = min(3, 4) = 3,
Video and video : relevance = min(2, 4) = 2.
Now let’s see which videos will be recommended for the following queries:
From video with k = 1, videos , and will be recommended.
From video with k = 3, videos and will be recommended.
From video with k = 4, no videos will be recommended.
Algorithm implementation — breadth first search
Store the input graph in an adjacency list .
vector<vector<pair<int, int>>> g;The bfs function performs a breadth-first search starting from the vertex and returns the number of visited vertices, excluding the vertex itself. During the search, we only move along edges whose weight is at least the given value .
int bfs(int start, int k)
{The shortest distance array is not needed in this problem — it's sufficient to simply track whether a vertex is visited. If vertex is visited, set used[i] = 1.
vector<int> used(n + 1);
used[start] = 1;Initialize a queue and add the starting vertex to it.
queue<int> q;
q.push(start);The number of visited vertices during the breadth-first search (excluding the starting vertex ) is counted in the variable .
int res = 0;Start the breadth-first search.
while (!q.empty())
{Extract the vertex from the queue .
int v = q.front(); q.pop();Iterate over all edges adjacent to vertex .
for (auto edge : g[v])
{Consider the edge (v, to) with weight .
int to = edge.first;
int kto = edge.second;If the edge weight is less than , skip this edge (moving along it is forbidden).
if (kto < k) continue;If the vertex is not visited yet, add it to the queue, mark it as visited, and increment the counter by .
if (used[to] == 0)
{
q.push(to);
used[to] = 1;
res++;
}
}
}Return the answer to the query.
return res;
}The main part of the program. Read the input data.
scanf("%d %d", &n, &qu);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
scanf("%d %d %d", &p, &q, &r);Add an undirected edge with weight to the adjacency list.
g[p].push_back({ q, r });
g[q].push_back({ p, r });
}Process the queries one by one.
while (qu--)
{
scanf("%d %d", &k, &v);Perform a breadth-first search (BFS) starting from vertex and print the number of vertices visited during the BFS.
printf("%d\n", bfs(v, k));
}Algorithm implementation — depth first search
Store the input graph in an adjacency list .
vector<vector<pair<int, int>>> g;The dfs function performs a depth-first search starting from vertex and returns the number of visited vertices. During the search, we only traverse edges whose weight is not less than the given value .
int dfs(int v, int k)
{Mark vertex as visited.
used[v] = 1;Count the number of vertices visited in the subtree rooted at during the depth-first search in the variable .
int res = 1;Iterate over all edges adjacent to vertex .
for (auto edge : g[v])
{Consider the edge (v, to) with weight .
int to = edge.first;
int kto = edge.second;If the weight is less than , skip this edge (moving along it is forbidden).
if (kto < k) continue;If vertex is not visited yet, perform a depth-first search starting from it. The number of vertices visited in the subtree rooted at is added to .
if (used[to] == 0)
res += dfs(to, k);
}
return res;
}The main part of the program. Read the input data.
scanf("%d %d", &n, &qu);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
scanf("%d %d %d", &p, &q, &r);Add an undirected edge with weight to the adjacency list.
g[p].push_back({ q, r });
g[q].push_back({ p, r });
}Process the queries one by one.
while (qu--)
{
scanf("%d %d", &k, &v);Perform a depth-first search starting from vertex . Print the number of vertices visited during the depth-first search, excluding the starting vertex .
used.assign(n + 1, 0);
printf("%d\n", dfs(v, k) - 1);
}