Tree III

题目链接

https://ac.nowcoder.com/acm/contest/9557/C

解题思路

代码1思路:
非严格的树上第二长路径,要么等于最长路径,要么等于最长路径-1。
当最长路径的个数多于1条的时候,答案就是最长路径,反之为最长路径-1。
num[i]表示以i为根的树最长子链的个数,d[i]表示以i为根的树最长子链的长度,sum表示最长路径的个数,mx表示最长路径的长度。
代码2思路:
保存最长路径长度和次长路径长度,保存最长子链长度和次长子链长度。
这种我只能看懂,但是理解不了细节,所以,自己看吧QWQ

两种代码的思想都是先跟新最长路径的信息再更新的最长子链的信息,读者自行理解,比较难解释。

AC代码1

const int N=1e5+10;

int cnt,head[N],mx,sum,num[N];
int d[N];

struct edge{int v,next;}e[N<<1];
void add(int u,int v){e[++cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}

void dfs(int x,int fa)
{
    num[x]=1;//!!!
    for(int i=head[x];i;i=e[i].next)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,x);

        if(d[x]+d[v]+1>mx) mx=d[x]+d[v]+1,sum=num[x]*num[v];//优先跟新以x为根树的最长路径的长度和个数
        else if(d[x]+d[v]+1==mx) sum+=num[x]*num[v];

        if(d[v]+1>d[x]) d[x]=d[v]+1,num[x]=num[v];//更新完最长路径的信息后,再更新以x为根的最长子链的长度和个数
        else if(d[v]+1==d[x]) num[x]+=num[v];
    }
}

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param e int整型vector 长度为n-1的数组,表示结点2到结点n的父结点
     * @return int整型
     */
    int tree3(vector<int> a) {
        for(int i=0;i<a.size();i++){
            add(i+2,a[i]);add(a[i],i+2);
        }
        dfs(1,0);
        return sum>1?mx:mx-1;
    }
};

AC代码2

const int N=1e5+10;

int cnt,head[N],ans1,ans2;
int d[N][3];

struct edge{int v,next;}e[N<<1];
void add(int u,int v){e[++cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}

void dfs(int x,int fa)
{
    d[x][1]=0;d[x][2]=-1;//!!!
    for(int i=head[x];i;i=e[i].next)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,x);
        int t=d[v][1]+d[x][1]+1;
        if(t>=ans1) ans2=max(ans2,ans1),ans1=t;//优先更新最长路径与次长路径的长度
        else if(t>=ans2) ans2=t;
        ans2=max(ans2,max(d[x][2]+d[v][1]+1,d[x][1]+d[v][2]+1));

        t=d[v][1]+1;
        if(t>=d[x][1]) d[x][2]=max(d[x][2],d[x][1]),d[x][1]=t;//更新最长子链与次长子链的长度
        else if(t>=d[x][2]) d[x][2]=t;
        d[x][2]=max(d[x][2],d[v][2]+1);
    }
}

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param e int整型vector 长度为n-1的数组,表示结点2到结点n的父结点
     * @return int整型
     */
    int tree3(vector<int> a) {
        for(int i=0;i<a.size();i++){
            add(i+2,a[i]);add(a[i],i+2);
        }
        dfs(1,0);
        return ans2;
    }
};
全部评论

相关推荐

不懂!!!:感觉你的项目描述太简单了,建议使用star描述法优化提炼一下,就是使用什么技术或方案解决了什么问题,有什么效果或成果,例如:对axios进行了二次封装,实现了请求的统一管理、错误的集中处理以及接口调用的简化,显著提高了开发效率和代码维护性,使用canvas技术实现了路线绘制功能,通过定义路径绘制函数和动态更新机制,满足了简化的导航可视化需求,提升了用户体验。像什么是使用其他组件库,基本功能描述就最好不要写到项目成果里面去了,加油
点赞 评论 收藏
分享
02-28 08:55
门头沟学院 Java
喜提窑鸡一筐:简历排版有一些问题,如果没有排版能力建议直接在超级简历用现成模板(无广,建议超级简历看到结一下账,别有那些太花里胡哨的,简历架构按:教育背景,实习经历,项目经历,其他能力概述/获奖经历,教育背景简单写点说明学校专业,在读时间即可,GPA好看可以写上去,不好看不用写,背景整体篇幅占15%以内,大篇幅给实习经历和项目经历,项目经历别写太多废话,HR都懒得看,通常按项目目标,具体工作1.2.3点/涉及技术栈,项目成果这样结构化展开,如果没有实现经历最好是有2-3段项目经历,其他最后补充点个人能力综述and获奖经历即可
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务