Book of evil

Book of Evil

https://ac.nowcoder.com/acm/problem/110130

稍微复杂的换根 DP,我能一发 A 掉的还是不多的...

题目大意

给出一棵有 个结点的树,其中 个结点 作特殊标记,令 代表结点 简单路径上边数,求有多少个点 ,满足


题解

不妨令 为根。

考虑结点 的最远标记点,可以在 的子树 内,也可以在 的子树外。

对这两种情况分别讨论。

的子树内情况比较简单,可以通过一次 dfs 求出。

内最远标记点到 的距离,如果 内没有标记点,则

但在这个 dfs 过程中,还要维护 内第二远标记点到 的距离 ,原因将在 解释。

的子树外情况比较复杂,但可以自然地想到是一个换根 DP:根 号点不存在子树外情况,已经可以求解。

假设 的任一儿子,此时对 有两种情况:

  • ,即 转移而来
  • ,即 不是由 转移而来。

以题目样例为例

其中 号点只有一个儿子 号点,那么 号点符合上述的第一种情况,也就是说, 号点的最远点就在孩子 号子树内。

此时,如果从 号点向 号点换根,如果使用 ,则 号点子树外的情况并未得到考虑,所以还需要记录 中所述的 ,并在换根过程中分类讨论。

其他细节请见代码。


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

template < typename Tp >
void read(Tp &x) {
    x = 0; int fh = 1; char ch = 1;
    while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if(ch == '-') fh = -1, ch = getchar();
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    x *= fh;
}

const int maxn = 100000 + 7;
const int maxm = 200000 + 7;
const int INF = 0x3f3f3f3f;

int n, m, d, dp[maxn], dp2[maxn];
bool mark[maxn];

int Head[maxn], Next[maxm], to[maxm], tot;
void addedge(int x, int y) {
    to[++tot] = y, Next[tot] = Head[x], Head[x] = tot;
}
void add(int x, int y){
    addedge(x, y); addedge(y, x);
}

void Init(void) {
    read(n); read(m); read(d);
    for(int i = 1, x; i <= m; i++) {
        read(x); mark[x] = true;
    }
    for(int i = 1, x, y; i < n; i++) {
        read(x); read(y);
        add(x, y);
    }
}

void dfs(int x, int fa) {
    dp[x] = dp2[x] = INF;
    for(int i = Head[x] ;i ; i = Next[i]) {
        int y = to[i];
        if(y == fa) continue;
        dfs(y, x);
        if(dp[y] != INF) {
            if(dp[x] == INF) dp[x] = dp[y] + 1;
            else {
                if(dp[y] + 1 > dp[x]) {
                    dp2[x] = dp[x];
                    dp[x] = dp[y] + 1;
                }
                else if(dp2[x] == INF) dp2[x] = dp[y] + 1;
                else dp2[x] = max(dp2[x], dp[y] + 1);
            }
        }
    }
    if(dp[x] == INF) if(mark[x]) dp[x] = 0;
}

int ans;

void dfs2(int x, int fa, int mov) {
    if(mov == INF && mark[fa]) mov = 1;
//    printf("id = %d, fa = %d, mov = %d, dp[x] = %d\n", x, fa, mov, dp[x]);
    if((dp[x] <= d || dp[x] == INF) && (mov <= d || mov == INF)) {
        ++ans;
    }
    for(int i = Head[x]; i; i = Next[i]) {
        int y = to[i];
        if(y == fa) continue;
        if(dp[x] == dp[y] + 1) {
            if(mov == INF && dp2[x] != INF) dfs2(y, x, dp2[x] + 1);
            else if(mov != INF && dp2[x] == INF) dfs2(y, x, mov + 1);
            else if(mov == INF && dp2[x] == INF) dfs2(y, x, INF);
            else dfs2(y, x, max(dp2[x], mov) + 1);
        }
        else {
            if(mov == INF && dp[x] != INF) dfs2(y, x, dp[x] + 1);
            else if(mov != INF && dp[x] == INF) dfs2(y, x, mov + 1);
            else if(mov == INF && dp[x] == INF) dfs2(y, x, INF);
            else dfs2(y, x, max(dp[x], mov) + 1);
        }
    }
}

void Work(void) {
    dfs(1, 0);
//    for(int i = 1; i <= n; i++) {
//        printf("%d : %d\n", i, dp[i]);
//    }
    dfs2(1, 0, INF);
    printf("%d\n", ans);
}

int main(void) {
    Init();
    Work();
    return 0;
}
全部评论

相关推荐

06-17 12:05
已编辑
南昌大学 Java
没想到我也能一周速通字节,javaer简历boss上被字节的测开捞了,项目是点评和rpc,之前0实习。简单说下时间线和面试内容吧,三面都是温柔的小姐姐,面试体验很好。总结来说基本没有问常规八股,都是围绕项目细节展开的场景问题,开放性问题,然后带一点八股。⌚️投递时间:5.28👋一面:6.9&nbsp;40min1.自我介绍2.项目拷打(超卖问题怎么解决的,由此展开聊了很久,各种细节拷打)3.算法题:将长度为n的数组分成m个和相等的子数组,求m的最大值,非hot100原题,leetcode698有道类似的,只给了10分钟,时间有点短没完全写出来,本来感觉都凉了但还是放过我了,感恩。4.高考成绩如何实现排...
一笑而过2222:一、抖音App长期无响应原因分析 1. 客户端问题:App版本过旧存在兼容性缺陷或代码逻辑错误;本地缓存、用户数据损坏影响加载;手机系统版本低、硬件性能不足导致不兼容。 2. 网络问题:网络信号差、无网络或DNS解析失败;代理设置错误、企业网络拦截抖音域名。 3. 服务端问题:启动依赖的API响应慢、服务端故障;CDN静态资源下载超时。 4. 第三方依赖问题:广告、推送等SDK初始化异常;系统服务未启用或关键权限缺失。 5. 其他原因:系统时间错误、后台应用抢占资源;用户频繁点击启动图标引发冲突。 二、电商平台兑奖系统测试用例 1. 功能测试:验证正常兑换、积分不足、限量商品重复兑换、库存实时更新及兑换记录查询功能。 2. 兼容性测试:在不同操作系统、浏览器环境下,确保功能正常和UI适配。 3. 性能与安全测试:模拟高并发检验系统稳定性;测试接口防刷机制;防御SQL注入攻击。 4. 异常场景测试:覆盖断网、服务端数据回滚、奖品过期等异常情况处理。 5. 用户体验测试:评估兑换流程是否简洁,错误提示是否明确,页面加载速度是否达标。 三、扩展建议 使用Firebase Crashlytics等工具上报启动日志排查抖音无响应问题;针对兑奖系统进行压测,重点监控TPS、错误率及响应时间 。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务