首页 > 其他分享 >32. CF-Tree Queries

32. CF-Tree Queries

时间:2023-01-23 19:44:29浏览次数:61  
标签:sz int 32 Tree CF dfs dep dfn maxn

题目链接

给一棵树,多次询问,每次给出若干个点,问是否存在从从根到叶的一条路径满足这些点到这条路径的距离均不超过 \(1\)。

容易想到,只需要 dfs 一遍预处理一下深度之类的信息,然后对于每次询问都取从根节点到最深的节点那条链,再判断一下其他的点就可以了。但是这样做为了保证复杂度,还需要用虚树之类的东西,就把问题复杂化了。

回到原来的问题,观察一下树的形态,不难发现满足要求的点要么自己在链上,要么父亲在链上,而前者的父亲必然也是在链上的。那么就相当于判断若干个点是否在一条链上。比较简单粗暴的做法是对深度排序后比较 LCA,相对巧妙的做法是对深度排序后通过 dfs 序判断下面的点是否在上面的点的子树中。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
vector<int> g[maxn];
int fa[maxn], dep[maxn];
int dfn[maxn], sz[maxn], dfscnt = 0;
void dfs(int u, int f, int d) {
    dfn[u] = ++dfscnt;
    sz[u] = 1;
    fa[u] = f;
    dep[u] = d;
    for (auto v : g[u]) {
        if (v == f)
            continue;
        dfs(v, u, d + 1);
        sz[u] += sz[v];
    }
}
int a[maxn];
void check() {
    int m;
    cin >> m;
    bool ok = true;
    for (int i = 1; i <= m; ++i) {
        cin >> a[i];
        a[i] = fa[a[i]];
    }
    sort(a + 1, a + m + 1, [](int x, int y) { 
        return dep[x] < dep[y]; 
    });
    for (int i = 2; i <= m; ++i) {
        if (dfn[a[i]] < dfn[a[i - 1]] ||
            dfn[a[i]] >= dfn[a[i - 1]] + sz[a[i - 1]]) {
            ok = false;
            break;
        }
    }
    cout << (ok ? "YES" : "NO") << '\n';
}
int main(int argc, char **argv) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    for (int i = 1, u, v; i < n; ++i) {
        cin >> u >> v;
        g[u].push_back(v), g[v].push_back(u);
    }
    dfs(1, 1, 1);
    while (q--) {
        check();
    }
}

标签:sz,int,32,Tree,CF,dfs,dep,dfn,maxn
From: https://www.cnblogs.com/theophania/p/p32.html

相关文章

  • dart win32 字符串指针
    获取窗口标题finalp=malloc<Pointer<Utf16>>(50);//在C语言中其实只需要传入一个字符串的指针就可以了,这里的话,是指针的指针GetWindowText(0x000908A6,p.value......
  • [CF1748F] Circular Xor Reversal
    题目描述Youhaveanarray$a_0,a_1,\ldots,a_{n-1}$oflength$n$.Initially,$a_i=2^i$forall$0\lei\ltn$.Notethatarray$a$iszero-i......
  • 跨年比赛记录(CF1777 赛时+补题)
    赛时开赛前,跟某位朋友说窝可能不会A,结果就真犯了离谱错误,一会儿没写输入一会儿写错输出,竟然9min才过A......
  • CF471D MUH and Cube Walls
    简要题意题目传送门平面上有两堵墙\(a,b\)。长度分别为\(n,w\)。求\(a\)墙顶端有多少个区间与\(b\)墙顶端一样。\(1\len,w\le2\times10^5,1\leqa_i,b_i\l......
  • 【题解】CF193D Two Segments
    题意给定一个\(1\simN\)的排列,在这个排列中选出两段互不重叠的区间,求使选出的元素排序后构成公差为1的等差数列的方案数。选出的两段区间中元素构成的集合相同时视为同一......
  • 【刷题记录】CF 交互构造题
    CF1779E给一张竞赛图,问一个\(n-1\)场淘汰赛之后可能的冠军有哪些。通过交互得到竞赛图的度。然后运用竞赛图的一些性质:可能的冠军\(u\)能够到达其他所有节点;......
  • LeetCode_单周赛_329
    2544.交替数字和代码1转成字符串,逐个判断classSolution{publicintalternateDigitSum(intn){char[]s=(""+n).toCharArray();intt......
  • 数据库损坏指南(2)--B-Tree Index损坏
    在理解PostgreSQL索引损坏之前,要理解PostgreSQL是如何实现b-tree索引的。B-tree索引结构PostgreSQL中,B-tree索引结构是根据Lehman和Yao的高并发B-tree算法实现的。逻辑上......
  • ABB 800XA学习笔记32:AC 800M硬件13
    这一篇学习笔记我在新浪博客记录过,地址是ABB800XA学习笔记32:AC800M硬件13_来自金沙江的小鱼_新浪博客(sina.com.cn)在这里我再记录一次,以免丢失继续学习2.8与AC800M控......
  • leetcode笔记——328周赛
    1.二维前缀和,二维差分304.二维区域和检索-矩阵不可变-力扣(LeetCode)二维前缀和怎么处理,注意加减的下标 2.2537.统计好子数组的数目-力扣(LeetCode)首先看到子数......