B 葱葱树
1000MS256MB
Description
这是一个在工作中的一个真实样例!聪哥十分庆幸他加入了ACM协会,并成功解决了这个需求,你能解决这个需求吗?
输入一棵大小为n有根树,节点编号为1到n且以编号为1的节点为根。这棵树的结点有0~9的权值。接下来给出Q个查询
每个查询输入一个结点的编号,输出以该节点为根的子树的叶子结点的权值数量。
Input
一个 N代表这棵树的结点的数量 N( N <= 10^5 )
接下来N-1行输入,每行输入u,v代表v是u的直接子节点, 结点编号从1开始(1 <= u,v <= N)
接下来输入一行,N个数字,代表每个结点的权值
接下来一行,有一个数字Q (Q <= 10 ^ 4)
接下来一行,有Q个数字,每个数字代表查询的结点编号
Output
输出Q行,每行9个数字,代表以该查询的节点为根的子树的叶子结点的0~9的权值的数量
Sample Input 1
5
1 2
2 3
2 4
2 5
1 2 3 4 4
5
5 4 3 2 1
Sample Output 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 1 2 0 0 0 0 0
0 0 0 1 2 0 0 0 0 0
题意
给定一棵树,以任一结点为根,输出以该节点为根的子树的叶子结点的权值数量。
思路
用vector模拟有向图的操作,把u的直接子结点存下来,查询的时候,用深搜操作搜索每一个直接子结点。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<int>g[100005];
ll quan[100005],ans=0,nine[20];
void bfs(ll ck){
for(int i=0;i<g[ck].size();i++){
//cout<<"i="<<i<<endl;
bfs(g[ck][i]);
}
nine[quan[ck]]++;
if(g[ck].size()!=0) nine[quan[ck]]--;
//cout<<"nine[ck]="<<nine[ck]<<endl;
}
int main(){
ios::sync_with_stdio(0);
ll n,q,i,s,t,check,ans=0;
cin>>n;
for(i=0;i<n-1;i++){
cin>>s>>t;
g[s].push_back(t);
}
for(i=1;i<=n;i++) cin>>quan[i];
cin>>q;
for(i=1;i<=q;i++){
cin>>check;
memset(nine,0,sizeof(nine));
bfs(check);
for(int j=0;j<=9;j++){
//if(g[check].size()!=0) nine[quan[check]]--;
cout<<nine[j]<<" ";
}
cout<<'\n';
}
return 0;
}