题目
在一颗有 个结点且以 1 为根节点树上,起初每个结点的初始权值为 0。
现在有 次操作,每次操作选择将以
为根节点的子树上的所有结点权值增加
。
求 次操作后从 1 到
每个结点的权值。
输入
第一个参数为 n,
第二个参数为边 的集合,其中
表示结点
与结点
之间有一条边,
第三个参数为 ,
第四个参数为 次询问的
的集合,
返回
从 1 到 每个结点的权值。
解题思路
使用 DFS 算法
记录与某个点相邻的所有点。
记录从 1 到 n 每个结点的权值。
一开始记录的是每个节点增加的权值,而不考虑节点的子树。
函数计算最终每个节点的权值。
从根节点 1 开始,深度优先遍历整个树。使用 记录点是否是遍历过,以区分是节点是子节点还是父节点。
如果是子节点,那么将该节点的权值加到子节点权值中,直到叶子节点结束。
C++代码
/**
* struct Point {
* int x;
* int y;
* };
*/
class Solution {
vector<vector<int>> next;
vector<int> vis;
vector<long> weight;
void dfs(int x){
for(int i=0; i<next[x].size(); ++i){
int e = next[x][i];
if(!vis[e]){
weight[e-1] += weight[x-1];
vis[e] = true;
dfs(e);
}
}
}
public:
/**
* 从 1 到 n 每个结点的权值。
* @param n int整型
* @param Edge Point类vector (u, v) 集合
* @param q int整型
* @param Query Point类vector Point.x 为题中 r, Point.y为题中 v
* @return long长整型vector
*/
vector<long> solve(int n, vector<Point>& Edge, int q, vector<Point>& Query) {
// write code here
next.resize(n+1);
for(int i=0; i<Edge.size(); ++i){
int u = Edge[i].x;
int v = Edge[i].y;
next[u].push_back(v);
next[v].push_back(u);
}
weight.resize(n, 0);
for(int i=0; i<q; ++i){
int r = Query[i].x;
int v = Query[i].y;
weight[r-1] += v;
}
vis.resize(n+1, false);
vis[1] = true;
dfs(1);
return weight;
}
}; 
京公网安备 11010502036488号