zoukankan      html  css  js  c++  java
  • CodeForces1328E dfs,树的深度

    题意

    给出一个有n个顶点的有根树,顶点的编号从1到n。树的根节点编号恒为1。
    一棵数是具有n-1条边的联通图。
    给出 m 个询问。第i个询问由 k_i 个不同的节点 v_i[1], v_i[2], …, v_i[k_i]组成. 你的任务是判断是否存在一条从根节点到u的路径,使得给出的k_i个节点要么在这条路径上,要么与该路径上的某个节点距离为1。

    题解

    • 针对单个询问,分析可得题目要求路径上所有节点的本身/儿子节点组成的集合必须包含给出的所有节点,聚焦结点的深度,容易意识到只需要check给出的节点中最深的节点到根节点的链就可以了。
    • 题目没有强制在线,所以可以考虑离线之后用一次dfs动态维护当前节点与根节点的链上所有节点及其儿子的集合,然后对每个节点到跟的链直接判断query
      时间复杂度O(N) + O(ΣK)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define PII pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define LL long long
    const int maxn = 2e5 + 10;
    const int mod = 1e9 + 7; 
    int N,M,S;
    struct Edge{
        int to,next;
    }edge[maxn * 2];
    int head[maxn],tot;
    void init() {
        for(int i = 0; i <= N ; i ++) head[i] = -1;
        tot = 0;
    }
    void add(int u,int v) {
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int deep[maxn];
    void dfs_deep(int u,int fa) {
        for(int i = head[u]; ~i; i = edge[i].next) {
            int v = edge[i].to;
            if(v == fa) continue;
            deep[v] = deep[u] + 1;
            dfs_deep(v,u);
        }
    }
    vector<vector<int> >Q[maxn];
    bool flag[maxn];
    bool ans[maxn];
    void dfs(int u, int fa) {
        for(int i = head[u]; ~i ; i = edge[i].next) {
            int v = edge[i].to;
            if(v == fa) continue;
            flag[v] = true;
        }
        for(int i = 0; i < Q[u].size(); i ++) {
            ans[Q[u][i][0]] = true;
            for(int j = 1; j < Q[u][i].size(); j ++) {
                if(!flag[Q[u][i][j]]) {
                    ans[Q[u][i][0]] = false;
                    break;
                }
            }    
        }
        for(int i = head[u]; ~i; i = edge[i].next) {
            int v = edge[i].to;
            if(v == fa) continue;
            dfs(v,u);
        }
        for(int i = head[u]; ~i; i = edge[i].next) {
            int v = edge[i].to;
            if(v == fa) continue;
            flag[v] = false;
        }
    }
    int main(){
        scanf("%d%d",&N,&M); init();
        for(int i = 1; i <= N - 1; i ++) {
            int u,v; scanf("%d%d",&u,&v);
            add(u,v); add(v,u);
        }
        deep[1] = 1;
        dfs_deep(1,-1);
        for(int i = 1; i <= M; i ++) {
            vector<int>P;
            P.push_back(i);
            int k; scanf("%d",&k);
            int t = 1;
            for(int i = 1; i <= k ; i ++) {
                int a; scanf("%d", &a);
                if(deep[a] > deep[t]) {
                    t = a;
                }
                P.push_back(a);
            }
            Q[t].push_back(P);
        }
        flag[1] = 1;
        dfs(1,-1);
        for(int i = 1; i <= M ; i ++) {
            if(ans[i]) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    js中的this指针(五)
    一个链式调用 setTimeout的例子
    js中的this指针(四)
    js中的this指针(三)
    NOJ 爱过
    Greatest Greatest Common Divisor HD5207
    Greatest Greatest Common Divisor HD5207
    Greatest Greatest Common Divisor HD5207
    Greatest Greatest Common Divisor HD5207
    Four Inages Strateg
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/13764397.html
Copyright © 2011-2022 走看看