• hdu-5927 Auxiliary Set


    Auxiliary Set

    Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

    Problem Description

    Given a rooted tree with n vertices, some of the vertices are important.
    An auxiliary set is a set containing vertices satisfying at least one of the two conditions:
    ∙ It is an important vertex
    ∙ It is the least common ancestor of two different important vertices.
    You are given a tree with n vertices (1 is the root) and q queries.
    Each query is a set of nodes which indicates the unimportant vertices in the tree. Answer the size (i.e. number of vertices) of the auxiliary set for each query.

    Input

    The first line contains only one integer T (T≤1000 ), which indicates the number of test cases.
    For each test case, the first line contains two integers n (1≤n≤100000 ), q (0≤q≤100000 ).
    In the following n -1 lines, the i-th line contains two integers ui,vi(1≤ui,vi≤n) indicating there is an edge between ui i and vi in the tree.
    In the next q lines, the i-th line first comes with an integer mi(1≤mi≤100000) indicating the number of vertices in the query set.Then comes with mi different integers, indicating the nodes in the query set.
    It is guaranteed that ∑qi=1mi≤100000 .
    It is also guaranteed that the number of test cases in which n≥1000   or ∑qi=1mi≥1000 is no more than 10.

    Output

    For each test case, first output one line "Case #x:", where x is the case number (starting from 1).
    Then q lines follow, i-th line contains an integer indicating the size of the auxiliary set for each query.

    Sample Input

    1 6 3 6 4 2 5 5 4 1 5 5 3 3 1 2 3 1 5 3 3 1 4

    Sample Output

    Case #1: 3 6 3

    Hint

    For the query {1,2, 3}: •node 4, 5, 6 are important nodes For the query {5}: •node 1,2, 3, 4, 6 are important nodes •node 5 is the lea of node 4 and node 3 For the query {3, 1,4}: • node 2, 5, 6 are important nodes

    
    
    题意:
    把一棵树上的点做一个标记,同时定义一个集合。集合中的节点满足应当满足两个要求中的一个:1.这个节点被标记为重点。2.这个节点是两个重点的LCA。

    现在给出q此查询,每次查询时给出的是没有被标记的节点的编号,你要输出集合的大小。

    思路:
    这个题做LCA显然不现实。现在,从最深的没有标记的点进行检查,要是这个点在集合里,那么它的必定有两个孩子节点(因为此时他的深度是最大的)。要是只有一个孩子节点的话,那么至少从它的这个孩子节点出发的LCA不是它,这种情况下要保留它,利用它判断它的祖先是否在集合中(同理,要是它有两个孩子节点也要保留)。要是它的孩子节点数是0,那么这个点对于祖先的贡献肯定是没有了,就删掉。
    #include "bits/stdc++.h"
    using namespace std;
    const int maxn = 100000 + 100;
    struct Edge {
        int next, to;
    }da[maxn*2];
    int tot;
    int par[maxn];
    int son[maxn];
    int dep[maxn];
    int head[maxn];
    int a[maxn], t[maxn];
    int N, q;
    void add_edge(int u, int v) {
        da[tot].to = v; da[tot].next = head[u];
        head[u] = tot++;
    }
    void dfs(int u, int fa, int d) {
        dep[u] = d; par[u] = fa; 
        for (int i = head[u]; i != -1; i = da[i].next) {
            int v = da[i].to;
            if (v != fa) dfs(v, u, d + 1), son[u]++; 
        }
    }
    bool cmp(int x, int y){return dep[x]>dep[y];}
    int main(int argc, char const *argv[])
    {
        int T;
        scanf("%d", &T);
        int Kcase = 0;
        while (T--) {
            memset(son, 0, sizeof(son));
            memset(head, -1, sizeof(head));
            scanf("%d%d", &N, &q);
            tot = 0;
            for (int i = 1; i <= N - 1; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                add_edge(u, v); add_edge(v, u);
            }
            dfs(1, -1, 1);
            printf("Case #%d:
    ", ++Kcase);
            while (q--) {
                int k;
                scanf("%d", &k);
                for (int i = 1; i <= k; i++) scanf("%d", a + i);
                for (int i = 1; i <= k; i++) t[a[i]] = son[a[i]];
                sort(a+1, a+1+k, cmp); int ans = N - k;
                for (int i = 1; i <= k; i++) {
                    if (t[a[i]] >= 2) ans++;
                    else if (t[a[i]] == 0) t[par[a[i]]]--;
                }
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    [置顶] 宏途_LCD调试流程.
    字典树的数据结构及基本算法的实现
    uva 10714 Ants(贪心)
    paip.输入法编程---增加码表类型
    chomp方法
    ios 限制输入长度
    我所理解的设计模式(C++实现)——策略模式(Strategy Pattern)
    Android用户界面 UI组件--AdapterView及其子类(一) ListView及各种Adapter详解
    C#系列教程——switch定义及使用
    局域网内linux由ip反解析主机名
  • 原文地址:https://www.cnblogs.com/cniwoq/p/7679202.html
Copyright © 2020-2023  润新知