树上数颜色

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代码

#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;
    }
}
posted @ 2022-12-03 20:43  Minza  阅读(187)  评论(0编辑  收藏  举报