树的直径

树的直径

概念

给定一棵树,树中每个边都有权值,树中两点之间的距离定义为连接两点的路径边权和.树中最远的两点之间的距离称之为树的直径,也就是树的最长链(偶尔也指代为一条路径).

树的直径有两种求法,都是O(n)的.一种是基于树形dp(之后再补上).一种是基于搜索.

搜索

我们随便找一个节点作为根(之前如果有根就不用换).进行一次搜索,找到距离根最远的节点p,然后再将p作为起点,寻找一个距离p最远的点q,那么pq就是直径.

简单证明:

假设根节点是直径的一端,那么根据直径的定义,p一定是直径的一端.

假设根节点不是直径的一端,而且找到的最远的p也不是直径的一端,假设直径的一端是p’.另一个端点是q,那么p’到q的距离可以拆分成 p’到根,根到q,如果将前半截更新成p到根,结果不会缩小.反证法得出p一定是直径(之一)的一端.

其实这里跑最短路也行,只不过搜索的复杂度是O(|V|+|E|)的.(参考<算法与实现>)

模板

牛客884A meeting

此题最后输出的是一半的直径(向上取整)

// 将代码中的dfs和bfs替换不会影响结果,dfs第二个参数填0
#include<bits/stdc++.h>

using namespace std;
#define MAXM 200001
struct NODE {
   
    int w;
    int e;
    int next; //next[i]表示与第i条边同起点的上一条边的储存位置
} edge[MAXM];
int cnt;
int head[MAXM];

void CFSInit() {
    // 链式前向星初始化
    cnt = 1;
    memset(head, 0, sizeof(head));
}

void add(int u, int v, int w) {
   
    edge[cnt].w = w;
    edge[cnt].e = v;    //edge[i]表示第i条边的终点
    edge[cnt].next = head[u]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值