zoukankan      html  css  js  c++  java
  • 【u219】最长链

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    现给出一棵N个结点二叉树,问这棵二叉树中最长链的长度为多少,保证了1号结点为二叉树的根。
    【提示】
    关于二叉树:
    二叉树的递归定义:二叉树要么为空,要么由根结点,左子树,右子树组成。左子树和右子树分别是一棵二叉树。
    请注意,有根树和二叉树的三个主要差别:
    1. 树的结点个数至少为1,而二叉树的结点个数可以为0;
    2. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2;
    3. 树的结点无左、右之分,而二叉树的结点有左、右之分。
    关于最长链:
    最长链为这棵二叉树中一条最长的简单路径,即不经过重复结点的一条路径。可以容易证明,二叉树中最长链的起始、结束结点均为叶子结点。


    【输入格式】

    输入文件chain.in的第1行为包含了一个正整数N,为这棵二叉树的结点数,结点标号由1至N。
    接下来N行,这N行中的第i行包含两个正整数l[i], r[i],表示了结点i的左儿子与右儿子编号。如果l[i]为0,表示结点i没有左儿子,同样
    地,如果r[i]为0则表示没有右儿子。

    【输出格式】

    输出文件chain.out包括1个正整数,为这棵二叉树的最长链长度。

    【数据规模】

    对于10%的数据,有N≤10;
    对于40%的数据,有N≤100;
    对于50%的数据,有N≤1000;
    对于60%的数据,有N≤10000;
    对于100%的数据,有N≤100000,且保证了树的深度不超过32768。

    Sample Input1

    6
    2 3
    4 5
    0 6
    0 0
    0 0
    0 0
    
    
    
    
    
    

    Sample Output1

    4
    

    【样例说明】

     4-2-1-3-6为这棵二叉树中的一条最长链。
    

    【题解】

    最长链是边的个数,而不是点的个数。

    求最长链的方法是,先从任意一个定点开始,找一个离该点最远的点k。

    然后再从k开始找一个离k最远的点m;

    m和k之间的距离就是最长链的长度。

    很容易记的东西。画张图就能理解吧。

    有动规还是什么的做法。不想知道了。

    【代码】

    #include <cstdio>
    #include <cstring>
    
    int n,l[100001] = {0},r[100001]={0},fa[100001] = {0},ma = 0,k =0;
    bool bo[100001];
    
    void sear_ch(int x,int tt) //表示走到了x这个点,已经走过的距离为tt 
    {
    	bo[x] = false;
    	if (tt > ma) //如果能够更新最大距离则更新 
    		{
    			ma = tt;
    			k = x;
    		}
    	if (bo[fa[x]]) //接下来这三行。查看是否能访问与之相连的节点。如果能就递增距离并访问 
    		sear_ch(fa[x],tt+1);
    	if (bo[l[x]])
    		sear_ch(l[x],tt+1);
    	if (bo[r[x]])
    		sear_ch(r[x],tt+1);
    }
    
    int main()
    {	
    	//freopen("F:\rush.txt","r",stdin);
    	scanf("%d",&n);
    	for (int i = 1;i <= n;i++)
    		{
    			scanf("%d%d",&l[i],&r[i]);
    			fa[l[i]] = i;
    			fa[r[i]] = i; //记录下这个节点的左儿子和右儿子的信息 
    		}
    	memset(bo,true,sizeof(bo));	//重置判重数组 
    	bo[0] = false;	 //bo[0]=false便于判断某节点是否有左儿子或有儿子。 连同判重一起用一个bo数组 
    	sear_ch(1,1);//从任意一个节点找离这个点最远的点k 
    	memset(bo,true,sizeof(bo));
    	bo[0] = false;
    	ma = 0;
    	sear_ch(k,1);//然后从点k开始再找一次离k最远的点m 
    	printf("%d
    ",ma-1);//ma是这两个点之间的点的个数。要求的是边的个数 
    	return 0;
    }



  • 相关阅读:
    Knockout应用开发指南 第八章:简单应用举例(2)
    微软ASP.NET站点部署指南(7):生产环境部署
    Knockout应用开发指南 第七章:Mapping插件
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(6)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(5)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(3)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(9)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(8)
    Microsoft Visual Studio .NET 2003 引导程序插件下载地址(非官方)
    Vs2010在没有安装SQL Server 2005/2008 Express时如何连接MDF数据文件?
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632356.html
Copyright © 2011-2022 走看看