( 数据结构专题 )【 树的直径 】

( 数据结构专题 )【 树的直径 】

定义:我们将一棵树T = ( V,E )的直径定义为max ( u,v ) ( u,v ∈ V ),也就是说,树中所有最短路径距离的最大值即为树的直径。

怎么求树的直径呢?

1、两次bfs(或者dfs)

方法:先从任意一点P出发,找离它最远的点Q,再从点Q出发,找离它最远的点W,W到Q的距离就是是的直径。( 记住就好了 )

 

例题:http://115.236.49.52:83/contest/1351

 

题意概括:
给定一棵树,找出两个点x,y,设dis(x,y)表示x与y之间的距离,最大化max(ax,ay)·dis(x,y)。

我们只需要计算出距离每一个点最远的点有多远即可。

 

树的直径: 两端点是树上距离最远的两点

求直径时,只需要用DFS求出距离任意一个点最远的点x,再找出距离x最远的点y,即得到树的一对直径端点x、y。

设树的直径两端点分别为u,v,那么u或v必然距离点x最远。
所以我们只需要求出直径后从直径两端点分别DFS求出每个点到直径两端点距离值即可。

 

代码:

#include <bits/stdc++.h>
#define int long long

using namespace std;

int n,via[200005],w[200005];
vector<int> G[200005];
int u[2],now;
int dep[200005];

void dfs( int x, int fa, int cnt, int op )
{
    if ( cnt>now ) {
        now = cnt;
        u[op] = x;
    }
    for ( int i=0; i<G[x].size(); i++ ) {
        int y = G[x][i];
        if ( y==fa ) continue ;
        dfs(y,x,cnt+1,op);
    }
}

void dfs2( int x, int fa, int cnt )
{
    dep[x] = max(dep[x],cnt);
    for ( int i=0; i<G[x].size(); i++ ) {
        int y = G[x][i];
        if ( y==fa ) continue ;
        dfs2(y,x,cnt+1);
    }
}

signed main()
{
    cin >> n;
    for ( int i=1; i<=n; i++ ) scanf("%lld",&w[i]);
    for ( int i=0; i<n-1; i++ ) {
        int a,b;scanf("%lld %lld",&a,&b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    now = 0;
    dfs(1,1,0,0);
    now = 0;
    dfs(u[0],u[0],0,1);
    dfs2(u[0],u[0],0);
    dfs2(u[1],u[1],0);
    int ans = 0;
    for ( int i=1; i<=n; i++ ) {
        ans = max(ans,dep[i]*w[i]);
    }
    cout << ans << endl;

    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值