游游的三色树(2022携程秋招第一批):题解

题目链接:https://www.nowcoder.com/questionTerminal/92756623de4146d1a573907478947987

一开始以为是换根dp,结果其实是个比较简单的树上计数题。

假设树的根是id=1的那个节点,定义siz[i][j][k]表示第i个节点,考虑其子树上每个节点,颜色为j的节点之和,k=0代表其子树,k=1代表除了其子树以外的区域,siz[i][j][0]用dfs直接求,siz[i][j][1]实际就是拿根节点(即整棵树)的siz减去siz[i][j][0],最后看是不是都>=1即可。

颜色3种,k有2种,dfs本身是O(n)的,所以总体是O(6*n)=O(n)的,就是可能常数有点大。

#include <iostream>
#include <string>
#include<vector>
#include<cstring>
using namespace std;
using ll = long long;
string s;
int n;
vector<int>g[100005];
ll siz[100005][3][2];
void dfs(int u, int fa){
    for(auto v : g[u]){
        if(v == fa){
            continue;
        }
        dfs(v,u);
        siz[u][0][0] += siz[v][0][0], siz[u][1][0] += siz[v][1][0], siz[u][2][0] += siz[v][2][0];
    }
}
void dfs2(int u, int fa){
    if(u != 1){
        siz[u][0][1] = siz[1][0][0]-siz[u][0][0];
        siz[u][1][1] = siz[1][1][0]-siz[u][1][0];
        siz[u][2][1] = siz[1][2][0]-siz[u][2][0];
    }
    for(auto v : g[u]){
        if(v == fa){
            continue;
        }
        dfs2(v,u);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cin >> n;
    cin >> s;
    memset(siz,0,sizeof siz);
    for(int i = 1;i <= n;++i){
        if(s[i-1] == 'r'){
            siz[i][0][0]++;
        }
        else if(s[i-1] == 'g'){
            siz[i][1][0]++;
        }
        else{
            siz[i][2][0]++;
        }
    }
    for(int i = 1,u,v;i < n;++i){
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1,0);
    dfs2(1,0);
    ll ans = 0;
    for(int i = 2;i <= n;++i){
        if(siz[i][0][0] >= 1 && siz[i][1][0] >= 1 && siz[i][2][0] >= 1 && siz[i][0][1] >= 1 && siz[i][1][1] >= 1 && siz[i][2][1] >= 1){
            ans++;
        }
    }
    cout << ans << "\n";
    return 0;
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

具体timeline可以看我历史帖子,共40分钟+聊天20分钟1.&nbsp;自我介绍&nbsp;项目介绍以下全部强项目相关2.&nbsp;深挖业务(10&nbsp;min),问项目成效3.&nbsp;聊天,个人问题一4.&nbsp;聊天,个人问题二5.&nbsp;开始问问技术,主要是爬虫方面,如何对抗?手段有哪些?(聊天,思路:首先分析常用反爬,L4,L7,行为,特征,硬件,POW,多特征联合等,再去说如何突破)6.&nbsp;部署如何容灾?具体库表设计?(聊天,按照实现如实说)7.&nbsp;失败如何感知?&nbsp;重做周期?(聊天,按照实现如实说,并讨论有什么不足,我给了一个改进方案,用死信队列)8.&nbsp;如何给定一个网址把所有东西都爬出来,有什么坑?(聊天,类比SiteMap,用数据结构抽象Site为一棵树,&nbsp;分布式以广搜的方式爬,以及具体实现;坑:蜜罐,RateLimit,等等。)9.&nbsp;如何加速消费?(聊天,联系MQ两种模型分别做叙述,&nbsp;并叙述到落地:直接在k8s中用Knative做扩容等;讨论)10.&nbsp;切面怎么用的?(聊天,如实说实现;讨论)11.&nbsp;做自定义逻辑,如何实现?(聊天,如实说实现,实现了插件管理器,热加载,实现层面上插件加载过程以及具体逻辑;&nbsp;并进一步讨论了对方业务自己的实现,讨论出了我的实现不足)12.&nbsp;juc场景题13.&nbsp;反问:聊天,聊20min总结:不同于一些找短板的部门,我认为面试官想找技术能力的长板,以及对业务的理解(0八股)。两面中绝大多数问题都是无法准备的,实现了有亮点就聊得来,没实现过就汗流浃背。#美团##Java#
点赞 评论 收藏
转发
点赞 1 评论
分享
牛客网
牛客企业服务