Auxiliary Set题解

F Auxiliary Set

树上LCA + DFS
注意一下输出格式!

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int t, n, q, ans;
int fa[N]; // 存储点i的父亲节点
int son[N], tmp[N];//存儿子节点
int un[N];//存不重要的点序列
int dep[N];//存深度
bool vis[N];
vector<int> vet[N];

void dfs(int u, int f, int d){
    fa[u] = f;
    dep[u] = d;
    vis[u] = true;
    for(int i = 0; i < vet[u].size(); i++){
        int j = vet[u][i];
        if(!vis[j]){
            //不能把父亲也加到儿子当中
            son[u] ++;
            dfs(j,u,d + 1);
        }
    }
}

bool cmp(int a, int b){
    return dep[a] > dep[b];
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> t;
    for(int tot = 1; tot <= t; tot ++){
        cin >> n >> q;
        for(int i = 1; i <= n; i++){
            vis[i] = false;
             son[i] = 0;
            vet[i].clear();
        }
        for(int i = 1; i <= n - 1; i ++){
            int a, b;
            cin >> a >> b;
            vet[a].push_back(b);
            vet[b].push_back(a);
        }
        dfs(1,0,0);
        cout << "Case #" << tot <<":" << endl;
        for(int j = 1; j <= q; j ++){
            int k;
            cin >> k;
            ans = n - k;
            for(int i = 1;i <= k; i++){
                cin >> un[i];
                tmp[un[i]] = son[un[i]];
            }
            //从深度更深的节点开始遍历
            sort(un + 1, un + 1 + k, cmp);
            for(int i = 1; i <= k; i++){
                if(tmp[un[i]] >= 2){
                    ans ++;
                }
                else if(tmp[un[i]] == 0){
                    tmp[fa[un[i]]] --;
                }
            }
            cout << ans << endl;
        }
    }
    return 0;
}

posted @ 2022-11-19 20:41  风归去  阅读(20)  评论(0编辑  收藏  举报