• 树的基础:树的直径


    Dev.C++树是一种特殊的图,有一些特殊的性质,直径就是其一。直径可以用2次爆搜或树形dp来求解。这里选用的是2次dfs
    这次,我不得不结合代码来解释了。

    #include<bits/stdc++.h>
    #define MAXN 100100
    using namespace std;
    int head[MAXN],n,cnt,maxv,maxdis;//从左往右:head,该树有n条边,cnt,maxv离原点最远的点,maxdis是直径的长度
    struct edge
    {
    	int nxt,to,w;
    }e[4*MAXN];
    void add(int u,int v)
    {
    	e[++cnt].nxt=head[u];
    	e[u].to=v;
    	head[u]=cnt;
    }
    void dfs(int u,int f,int dis)//u为这次搜索的原点,f是他的父亲,dis是u离原原点的距离
    {
    	if(maxdis<dis)//第二次爆搜时当已算出直径比原点到远点距离短时,更新直径
    	{
    		maxdis=dis;
    		maxv=u;//更新maxv
    	}
    	for(int i=head[u];i!=0;i=e[i].nxt)
    	{
    		int v=e[i].to,w=e[i].w;//方便使用
    		if(v==f)continue;//当e[i].to即原点指向的点是他爸时,如果再跑,就往回跑了,要continue掉,不然会死递归
    		dfs(v,u,dis+w);//以这次原点他孩子(不会出现他爸,上面有特判)为原点,这次原点为父亲,向下扩增
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		add(y,x);//建双向边
    	}
    	dfs(1,-1,0);
    	maxdis=0;
    	dfs(maxv,-1,0);
    	cout<<maxdis<<endl;
    	return 0;
    }
    

    代码那里有解释,我不解释代码了。解释解释思想。


    在树上任意找一点u,找到离这一点最远的点maxv。
    再以maxv为u,找到离maxv最远的点。在寻找过程中,将第二个u和第二个maxv之间的距离加出来,就是直径的距离。
    至于为什么,我太菜了,我也不知道。但是这就是爆搜求直径的方法了。


    树的直径是一个很基础的内容,一定要掌握下来哦!

  • 相关阅读:
    一个匪夷所思的错误
    String.Format 摘录
    DISTINCT的问题
    showModalDialog()、showModelessDialog()方法使用详解
    vbscript变量的特点
    vuecli3安装过程
    @vuecli3创建项目报错:ERROR command failed: npm install loglevel error registry=https://registry.npm.taobao.org di
    @vuecli3安装element组件过程
    dialogPostRun 覆盖方法class Dialog 动态创建
    清除重复记录只保留一条
  • 原文地址:https://www.cnblogs.com/riced/p/13778039.html
Copyright © 2020-2023  润新知