• Codevs 1814 最长链


    1814 最长链
    时间限制: 1 s
    空间限制: 256000 KB
    题目等级 : 钻石 Diamond
    题目描述 Description
    现给出一棵N个结点二叉树,问这棵二叉树中最长链的长度为多少,保证了1号结点为二叉树的根。
    输入描述 Input Description
    输入的第1行为包含了一个正整数N,为这棵二叉树的结点数,结点标号由1至N。
    接下来N行,这N行中的第i行包含两个正整数l[i], r[i],表示了结点i的左儿子与右儿子编号。如果l[i]为0,表示结点i没有左儿子,同样地,如果r[i]为0则表示没有右儿子。
    输出描述 Output Description
    输出包括1个正整数,为这棵二叉树的最长链长度。
    样例输入 Sample Input
    5
    2 3
    4 5
    0 6
    0 0
    0 0
    样例输出 Sample Output
    4
    数据范围及提示 Data Size & Hint
    【样例说明】
    4-2-1-3-6为这棵二叉树中的一条最长链。
    【数据规模】
    对于10%的数据,有N≤10;
    对于40%的数据,有N≤100;
    对于50%的数据,有N≤1000;
    对于60%的数据,有N≤10000;
    对于100%的数据,有N≤100000,且保证了树的深度不超过32768。
    【提示】
    关于二叉树:
    二叉树的递归定义:二叉树要么为空,要么由根结点,左子树,右子树组成。左子树和右子树分别是一棵二叉树。
    请注意,有根树和二叉树的三个主要差别:
    1. 树的结点个数至少为1,而二叉树的结点个数可以为0;
    2. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2;
    3. 树的结点无左、右之分,而二叉树的结点有左、右之分。
    关于最长链:
    最长链为这棵二叉树中一条最长的简单路径,即不经过重复结点的一条路径。可以容易证明,二叉树中最长链的起始、结束结点均为叶子结点。
    分类标签 Tags
    最小生成树 图论

    /*
    两遍Bfs.
    第一次找最远点.
    第二次用最远点扩展最长链.
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define MAXN 100001
    #define MAXM 1000001*2
    using namespace std;
    int n,tot,head[MAXN],dis[MAXN],maxtot,maxt;
    struct data{
        int v,next;
    }
    e[MAXM];
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v){
        e[++tot].v=v;
        e[tot].next=head[u];
        head[u]=tot;
    }
    int bfs(int u){
        queue<int>q;q.push(u);memset(dis,-1,sizeof(dis));dis[u]=0;maxtot=0;
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].next){
                int v=e[i].v;
                if(dis[v]==-1){
                    dis[v]=dis[u]+1;q.push(v);
                    if(dis[v]>maxtot){
                        maxtot=dis[v];maxt=v;
                    }
                }
            }
        }
        return maxt;
    }
    int main(){
        int x;
        n=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=2;j++) {
                x=read();if(x) add(i,x);add(x,i);}
        int t=bfs(1);
        bfs(t);
        printf("%d",maxtot);
        return 0;
    }
    /*
    DP.
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 200001
    using namespace std;
    int f[MAXN][3],n,m,cut,ans,tot,head[MAXN],son1,son2,son[MAXN][3];
    struct data{int v,next;}e[MAXN*2];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v)
    {
        e[++cut].v=v;
        e[cut].next=head[u];
        head[u]=cut;
    }
    int dp1(int u,int fa)
    {
        int v=son[u][1],v2=son[u][2];
        if(v) dp1(v,u);
        if(v2) dp1(v2,u);
        if(!v&&!v2) return f[u][1]=1;
        f[u][1]=max(f[u][1],max(f[v][1]+1,f[v2][1]+1));
        f[u][2]=max(f[u][2],f[v][1]+f[v2][1]+2),ans=max(ans,f[u][2]);
        return f[u][1];
    }
    int main()
    {
        int x,y;
        n=read();
        for(int i=1;i<=n;i++)
        {
            x=read(),y=read();
            if(i==1) son1=x,son2=y;
            if(x) son[i][1]=x,add(i,x);
            if(y) son[i][2]=y,add(i,y);
        }
        ans=max(ans,dp1(1,0));
        printf("%d",ans-2);
        return 0;
    }
    
  • 相关阅读:
    1203 有穷自动机
    [转]HTTP协议详解
    JavaScript中的正则表达式
    [译]JavaScript insertAdjacentHTML
    [译]Autoprefixer:用最可行的方式处理浏览器前缀的CSS后处理器
    [译]JavaScript 错误和处理
    [译]CSS content
    [译]当你在浏览器输入url后发生了什么
    display的小故事
    移动web屏幕适配方案
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070792.html
Copyright © 2020-2023  润新知