假设有一棵n个点的树,每个点有一个颜色,编号为i的点颜色为col[i],给定m组询问,每次询问给定u,v,a,b,表示询问到u到v的简单路径上,出现次数大于等于a且小于等于b的有多少种,用c++做, 输入格式: 第一行包含两个整数n和m,表示树的节点数和询问次数。 第二行包含n个整数,表示每个节点的颜色。 接下来n-1行,每行包含两个整数u和v,表示树中的一条边。 接下来m行,每行包含四个整数u、v、a和b,表示一个询问。 输出格式: 对于每个询问,输出一个整数,表示满足条件的路径数量。
时间: 2024-04-15 19:31:13 浏览: 48
我们可以使用深度优先搜索(DFS)算法来解决这个问题。首先,我们需要构建树的数据结构,可以使用邻接表来表示。
```cpp
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 100005; // 树的最大节点数
vector<int> adj[MAXN]; // 邻接表
int color[MAXN]; // 每个节点的颜色
int pathCount[MAXN][MAXN]; // 记录路径上每种颜色的出现次数
void dfs(int u, int parent) {
for (int v : adj[u]) {
if (v == parent) continue; // 避免重复访问父节点
for (int i = 0; i < MAXN; i++) {
pathCount[u][i] += pathCount[v][i]; // 累加子节点的颜色计数
}
}
pathCount[u][color[u]]++; // 记录当前节点的颜色计数
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> color[i];
}
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(1, -1); // 从根节点开始遍历树
for (int i = 0; i < m; i++) {
int u, v, a, b;
cin >> u >> v >> a >> b;
int count = 0;
for (int j = 1; j <= n; j++) {
if (pathCount[u][j] - pathCount[v][j] >= a && pathCount[u][j] - pathCount[v][j] <= b) {
count++;
}
}
cout << count << endl;
}
return 0;
}
```
请注意,为了优化查询过程,我们预先计算了每个节点到根节点的路径上,每种颜色的出现次数。然后在每次询问时,只需要计算在路径上满足条件的颜色数量即可。
希望这个代码能对你有所帮助!如果还有其他问题,请随时提问。
阅读全文