奖金(改错)
奖金(bonus)
【题目描述】
巨硬公司是微软公司的竞争对手,今年为了鼓励员工们的积极性决定发放 q 次奖金,奖金的发放是以 部门领导为单位,巨硬公司的体系为一个领导和若干的该领导的下属,而其下属也可以是其他员工的领导。 巨硬公司的董事会决定,每次选定一个编号为 i 的领导(已知该公司最大领导的编号为 1 ),给领导 及其全部下属发放奖金。
问经过 q 次发放后,每个员工(包含领导)最终能够获得多少万的奖励。
【输入格式】
第一行两个数 n 和 q,表示员工总数,q表示发放q次奖金。
接下来n行每行两个正整数 x 和 y,表示 x 和 y 之间存在工作上的上下级关系,但x和y可能x是y的上级,也 可能y是x的上级。
再接下里q行每行两个正整数 id 和 f ,表示给编号为 id 的员工及其全部下属每人发放 f 万的奖金。
【输出格式】
输出n个数据,以空格隔开,代表的是从编号 1 至 n 个领导获得奖金的总数
【数据范围与约定】
对于50%的数据,1<=n,q<=2000
对于另外10%的数据,有y=x+1
对于100%的数据,1<=n,q<=2*10^5,0<=f<=10^4
代码实现:
#include<bits/stdc++.h>
using namespace std;
int father[1000005],sum[1000005];
vector<int> e[1000005];
void FindFather(int s=1,int f=0){ //寻找父亲 s表示编号,f表示此节点父亲(领导)
father[s]=f;
for(int i=0;i<e[s].size();i++){
int c=e[s][i];
if(c==f){
continue;
}
FindFather(c,s);
}
}
void GetAns(int s=1,int b=0){
sum[s]+=b;
for(int i=0;i<e[s].size();i++){ //循环存储该节点奖金值
int c=e[s][i];
if(c==father[s]){
continue;
}
GetAns(c,sum[s]);
}
}
int main(){
freopen("bonus.in","r", stdin); //注意文件操作
freopen("bonus.out","w", stdout);
int n,q;
scanf("%d%d",&n,&q);
for(int i=0;i<n-1;i++){ //n个节点一共n-1条边
int a,b;
scanf("%d%d",&a,&b);
e[a].push_back(b); //无向存边
e[b].push_back(a);
}
FindFather();
for(int i=0;i<q;i++){
int id,f;
scanf("%d%d",&id,&f); //id表示节点编号,f表示奖金
sum[id]+=f;
}
GetAns();
for(int i=1;i<=n;i++){
printf("%d ",sum[i]);
}
return 0;
}