L2-038 病毒溯源 (25 分)

看懂别人的做法是一回事,自己会做又是另一回事。别人的做法再优雅,不是你的风格。对你也无用。只有你自己独立做出来的题目。用你自己总结出的体系去做出来的解法。充满你自己风格的解法。才是你真正的东西。

思路

1.先建好树
2.正常dfs遍历
3.你一开始设置maxdeep = 1最后又return maxdeep 其实你已经安顿好了你的叶子结点。嗯安顿好你的叶子结点是dfs中最重要的事情。
4.因为你已经安顿好了,于是你调用自己求出这个子树的深度。
5.如果儿子的深度 + 1大于最大的深度maxdeep(也就是以这个儿子为儿子导致的深度最深)。那么最大的深度就是这个儿子的深度 + 1了儿子就变成这个
6.题目中说了,如果相同,那么序号小的在优先,于是就有了那个相等的时候的情况。

代码

#include<bits/stdc++.h>

using namespace std;

const int N = 1e4+10;

vector<int> v[N];
int n;
int rt;
int son[N];
bool st[N];

int dfs(int root){
    
    int maxdeep = 1;
    
    for(auto it:v[root]){
        
        int erdeep = dfs(it);
        
        if(erdeep + 1> maxdeep){
            maxdeep = erdeep + 1;
            son[root] = it;
        }
        
        else if(erdeep + 1 == maxdeep){
            son[root] = min(son[root],it);
        }
        
    }
    return maxdeep;
}

int main(){
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    memset(son,-1,sizeof son);
    
    cin>>n;
    for(int i=0;i<n;i++){
        int k;
        cin>>k;
        while(k--){
            int t;
            cin>>t;
            st[t] = true;
            v[i].push_back(t);
        }
    }
    
    for(int i=0;i<n;i++){
        if(!st[i])rt = i;
        
    }
    
    cout<<dfs(rt)<<endl;
    
    cout<<rt;
    while(son[rt]!=-1){
        cout<<" "<<son[rt];
        rt = son[rt];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值