树上数颜色

7899:树上数颜色
时间限制(普通/Java):3000MS/9000MS 内存限制:250000KByte

描述

给定一个n个点、n-1条边的树(编号为1~n,其中1号为根),每个点有一个颜色,每次询问以x为根的子树中有多少种不同的颜色。

输入

第一行两个整数n,m(2<=n<=100000, 1<=m<=n),表示有n个顶点,m次查询。
第二行n个整数,表示每个点的颜色(颜色值在1~n之间)。
接下来n-1行每行u和v,表示存在一条从u到v的双向边。
接下来有m行,每行一个正整数x,表示待查询的子树的根(1<=u, v, x<=n)。
数据保证是一棵树。

输出

输出m行,每行为查询的结果。

样例输入

4 3
1 1 2 3
1 2
2 3
1 4
1
2
4

样例输出

3
2
1

思路

暴力深搜,深搜到叶子结点后回溯从下往上把集合往上合并,记录以每个根节点的子树的颜色个数

AC代码

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
#include <bits/stdc++.h> using namespace std; int n,m; vector<int>bian[100010]; int color[100010]; set<int> dfs(int k,int fa) { set<int>temp{color[k]}; for(auto i:bian[k]) { if(i!=fa) { set<int>tem=dfs(i,k); temp.insert(tem.begin(),tem.end()); } } color[k]=temp.size(); return temp; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin>>n>>m; int st,en; for(int i=1;i<=n;i++) { cin>>color[i]; } for(int i=1;i<n;i++) { cin>>st>>en; bian[st].push_back(en); bian[en].push_back(st); } dfs(1,1); while (m--) { cin>>st; cout<<color[st]<<endl; } }

本文作者:Minza

本文链接:https://www.cnblogs.com/minz-io/p/16948755.html

posted @   Minza  阅读(232)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开