[CF1790F] Timofey and Black-White Tree 题解

[CF1790F] Timofey and Black-White Tree 题解

题目描述

ZYH 有一棵 n 个节点的树,最初 c0 号节点是黑色,其余均为白色。

给定操作序列 c1,c2,,cn1,第 i 次操作表示将 ci 号节点染黑。每次操作后,输出距离最近的两个黑点间的距离。两点 u,v 间的距离定义为 uv 的路径上经过的边的条数。

多组数据,1T104,2n2×105,n2×105,节点编号均在 [1,n] 内。

思路

每次加入一个点暴力统计一遍答案,如果当前距离超过了答案就跳出。

这看着好像很暴力,似乎是平方的,但是其实是根号的,由于这个结论:

在一棵树上随机选择 n 个点它们之间的最小距离一定不超过 n

证明:

对于一条链的情况,最坏情况是 n 个点隔 n,这种情况下的最小距离最大是 n,而对于一棵树,它是不比链的情况优的。

所以对于前 n 个点,考虑最坏情况,即每次跑 n 个点,而对于后面 nn 左右个点,根据前面已经证明过的结论,只要我们一旦超过答案就跳出,它们最多会跑 n 次,这是最坏情况,因此总的时间复杂度是 O(nn),类似于根号分治。

// Problem: Timofey and Black-White Tree
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF1790F
// Memory Limit: 250 MB
// Time Limit: 4000 ms
// Powered by CP Editor (https://cpeditor.org)
 
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 2e5 + 10;
 
vector<int> g[N];
int q[N], dist[N], ans;
bool vis[N];
inline void bfs(int s) {
    queue<int> q;
    q.push(s);
    dist[s] = 0;
    while(q.size()) {
        int t = q.front();
        q.pop();
        if(dist[t] >= ans) break;
        for(auto v : g[t]) {
            if(dist[v] <= dist[t] + 1) continue;
            dist[v] = dist[t] + 1;
            q.push(v);
        }
    }
}
int n;
inline void work() {
    n = read();
    q[0] = read();
    for(int i = 1; i <= n; i ++) g[i].clear();
    memset(dist, 0x3f, n + 1 << 2);
    for(int i = 1; i < n; i ++) q[i] = read();
    for(int i = 1, a, b; i < n; i ++) {
        a = read(), b = read();
        g[a].push_back(b), g[b].push_back(a);
    }
    ans = n + 1;
    bfs(q[0]);
    for(int i = 1; i < n; i ++) ans = min(ans, dist[q[i]]), bfs(q[i]), write(ans), putchar(' ');
    puts("");
    return ;
}
 
int main() {
    int T = read();
    while(T --) work();
    return 0;
}
posted @   MoyouSayuki  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
:name :name
点击右上角即可分享
微信分享提示