zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    vim 乱码问题的方法参考
    Node.js的原型继承函数 util.inherits
    UML类图画法及其之间的几种关系
    repo 小结
    Js_Eval方法
    Js_数组操作
    Js_字体滚动换颜色
    Js_图片轮播
    Jq_网站顶部定时折叠广告
    Js_网站右下角悬浮视窗可关闭广告
  • 原文地址:https://www.cnblogs.com/cniwoq/p/7679202.html
Copyright © 2011-2022 走看看