题目描述
思路分析
本题所求的实际上是树的直径,即树中的任意两个结点之间的最大距离
采用的方法是dfs
从根节点开始遍历,对于每一个被dfs的结点m,返回此结点m到所有叶子结点的距离最大的那个即d1,同时在dfs过程当中记录结点m到所有叶子结点的距离第二大的那个,即d2
那么最终答案就是对于每一个结点取res=res(res,d1+d2)
举个栗子:
设最下面的1--4的编号分别为5,6,7,8
从1开始dfs,首先进入2,然后对2dfs,进入3,然后对3进行dfs,对3dfs的时候,又进入5,对5dfs,此时由于结点5没有分支,所以这一次dfs得到d1=d2=0,返回给结点3的值为d1+1=1,之后3也算dfs完毕,结果:d1=1,d2=0,返回给2的值为d1+1=2,然后开始对4dfs,此时会进入下一层,依次对6,7,8进行dfs均返回d1+1=1,所以对于4dfs的结果是d1=1,d2=1,返回给2的值为2,所以最终2dfs结果是d1=2,d2=2,此时得到ans最大值:d1+d2=4.返回给结点1的值为d1+1=3,所以对1dfs完毕得到的结果是d1=3,d2=0,最终返回的结果为d1+1=4,同时保留答案ans=4文章来源:https://www.toymoban.com/news/detail-704674.html
最后再提示一下,虽然树的本质是无向图,但是在建立边的时候,直接建成从上往下指的有向边即可,因为dfs的时候是从上往下的。当然建立成无向边也可以,只不过需要一个bool数组标记已经遍历过的结点,防止进入无限循环。文章来源地址https://www.toymoban.com/news/detail-704674.html
满分代码
#include<iostream>
#include<cstring>
using namespace std;
const int N=20010;
int e[N],ne[N],h[N],idx;
int n,m;
int ans;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dfs(int u)
{
int d1=0,d2=0;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
int d=dfs(j);
if(d>=d1)d2=d1,d1=d;
else if(d>=d2)d2=d;
}
ans=max(ans,d1+d2);
return d1+1;
}
int main()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
for(int i=2;i<=n+m;i++)
{
int x;
scanf("%d",&x);
add(x,i);
}
dfs(1);
cout<<ans;
return 0;
}
到了这里,关于【ccf-csp题解】第四次csp认证-第四题-网络延时-树的直径的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!