1850:【07NOIP提高组】树网的核 题解

题面

【题目描述】

设 T = ( V , E , W ) 是 一 个 无 圈 且 连 通 的 无 向 图 ( 也 称 无 根 树 ) , 每 条 边 带 有 正 整 数 的 权 , 我 们 称 T 为 树 网 ( t r e e n e t w o r k ) , 其 中 V , E 分 别 表 示 结 点 与 边 的 集 合 , W 表 示 各 边 长 度 的 集 合 , 并 设 T 有 n 个 结 点 。 设T=(V,E,W)是一个无圈且连通的无向图(也称无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并设T有n个结点。 T=(VEW)T(treenetwork)VEWTn

路 径 : 树 网 中 任 何 两 个 结 点 a , b 都 存 在 唯 一 的 一 条 简 单 路 径 , 用 d ( a , b ) 表 示 以 a , b 为 端 点 的 路 径 长 度 , 它 是 该 路 径 上 各 边 长 度 之 和 。 我 们 称 d ( a , b ) 为 a , b 两 个 结 点 间 的 距 离 。 路径:树网中任何两个结点a,b都存在唯一的一条简单路径,用d(a,b)表示以a,b为端点的路径长度,它是该路径上各边长度之和。我们称d(a,b)为a,b两个结点间的距离。 a,bd(a,b)a,bd(a,b)a,b

一 点 v 到 一 条 路 径 p 的 距 离 为 该 点 与 p 上 的 最 近 的 结 点 的 距 离 : 一点v到一条路径p的距离为该点与p上的最近的结点的距离: vpp

d ( v , p ) = m i n ( d ( v , u ) , u 为 路 径 p 上 的 结 点 ) d(v,p)=min(d(v,u),u为路径p上的结点) d(v,p)=min(d(v,u),up)

树 网 的 直 径 : 树 网 中 最 长 的 路 径 称 为 树 网 的 直 径 。 对 于 给 定 的 树 网 T , 直 径 不 一 定 是 唯 一 的 , 但 是 可 以 证 明 : 各 直 径 的 中 点 ( 不 一 定 恰 好 是 某 个 结 点 , 可 能 在 某 条 边 的 内 部 ) 是 唯 一 的 , 我 们 称 该 点 为 树 网 的 中 心 。 树网的直径:树网中最长的路径称为树网的直径。对于给定的树网T,直径不一定是唯一的,但是可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。 T

偏 心 距 E C C ( F ) : 树 网 T 中 距 路 径 F 最 远 的 结 点 到 路 径 F 的 距 离 , 即 E C C ( F ) = m a x ( d ( v , F ) , v ∈ V ) 。 偏心距ECC(F):树网T中距路径F最远的结点到路径F的距离,即 ECC(F)=max(d(v,F),v∈V)。 ECCFTFFECCF=max(d(v,F),vV)

任 务 : 对 于 给 定 的 树 网 T = ( V , E , W ) 和 非 负 整 数 S , 求 一 个 路 径 F , 它 是 某 直 径 上 的 一 段 路 径 ( 该 路 径 的 两 端 均 为 树 网 中 的 结 点 ) , 其 长 度 不 超 过 S ( 可 以 等 于 S ) , 使 偏 心 距 E C C ( F ) 最 小 , 我 们 称 这 个 路 径 为 树 网 T = ( V , E , W ) 的 核 ( C o r e ) 。 必 要 时 , F 可 以 退 化 为 某 个 结 点 。 一 般 来 说 , 在 上 述 定 义 下 , 核 不 一 定 只 有 一 个 , 但 是 最 小 偏 心 距 是 唯 一 的 。 任务:对于给定的树网T=(V,E,W)和非负整数S,求一个路径F,它是某直径上的一段路径(该路径的两端均为树网中的结点),其长度不超过S(可以等于S),使偏心距ECC(F)最小,我们称这个路径为树网T=(V,E,W)的核(Core)。必要时,F可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但是最小偏心距是唯一的。 T=VEWSFSS使ECCFT=VEWCoreF退

下 面 的 图 给 出 了 一 个 树 网 的 一 个 实 例 。 图 中 , A − B 与 A − C 是 两 条 直 径 , 长 度 均 为 20 。 点 W 是 树 网 的 中 心 , E F 边 的 长 度 为 5 。 如 果 指 定 S = 11 , 则 树 网 的 核 为 路 径 D E F G ( 也 可 以 取 为 路 径 D E F ) , 偏 心 距 为 8 , 如 果 指 定 S = 0 ( 或 s = 1 、 s = 2 ) , 则 树 网 的 核 为 结 点 F , 偏 心 距 为 12 。 下面的图给出了一个树网的一个实例。图中,A-B与A-C是两条 直径,长度均为20。点W是树网的中心,EF边的长度为5。如果指定S=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为8,如果指定S=0(或s=1、s=2),则树网的核为结点F,偏心距为12。 ABAC20WEF5S=11DEFGDEF8S=0(s=1s=2),F12

【输入】

包 含 n 行 : 包含n行: n

第 1 行 , 两 个 整 数 n 和 s , 中 间 用 一 个 空 格 隔 开 。 其 中 n 为 树 网 的 核 的 长 度 的 上 界 。 设 结 点 编 号 依 次 为 1 , 2 , … . , n 。 第1行,两个整数n和s,中间用一个空格隔开。其中n为树网的核的长度的上界。设结点编号依次为1,2,….,n。 1nsn12.n

从 第 2 行 到 第 n 行 , 每 行 给 出 3 个 用 空 格 隔 开 的 正 整 数 , 依 次 表 示 每 一 条 边 的 两 个 端 点 编 号 和 长 度 。 例 如 , “ 247 ” 表 示 连 接 结 点 2 与 4 的 边 的 长 度 为 7 。 从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7 ”表示连接结点2与4的边的长度为7。 2n3247247

所 给 的 数 据 都 是 正 确 的 , 不 必 检 验 。 所给的数据都是正确的,不必检验。

【输出】

只 有 一 个 非 负 整 数 , 为 指 定 意 义 下 的 最 小 偏 心 距 。 只有一个非负整数,为指定意义下的最小偏心距。

【输入样例】

5 2
1 2 5
2 3 2
2 4 4
2 5 3

【输出样例】

5

【提示】

【输入输出样例2】

输入:
8 6 
1 3 2 
2 3 2 
3 4 6 
4 5 3 
4 6 4 
4 7 2 
7 8 3
输出:
5

【限制】

40 40 40% 的 数 据 满 足 : 5 ≤ n ≤ 15 的数据满足:5≤n≤15 5n15

70 70 70% 的 数 据 满 足 : 5 ≤ n ≤ 80 的数据满足:5≤n≤80 5n80

100 100 100% 的 数 据 满 足 : 5 ≤ n ≤ 300 , 0 ≤ s ≤ 1000 。 边 长 度 为 不 超 过 1000 的 正 整 数 。 的数据满足:5≤n≤300,0≤s≤1000。边长度为不超过1000的正整数。 5n300,0s10001000

题解

毒 瘤 题 啊 , 连 续 提 交 2 次 全 T L E , 实 在 毒 瘤 啊 ! 毒瘤题啊,连续提交2次全TLE,实在毒瘤啊! 2TLE

code:

#include<cstdio>
#include<algorithm>
#include<cstring>
const int inf=0x3f3f3f3f;
using namespace std;
int n,s,a,b,c,maxx=0,mxi,mxj;
int dis[305][305];
int read(){
    int ans=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){
    	if(c=='-')f=-1;
    	c=getchar();
    }
    while(c>='0'&&c<='9'){
    	ans=ans*10+c-48;
    	c=getchar();
    }
    return ans*f;
} 
int main(){
    n=read();s=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j)dis[i][j]=inf;
    for(int i=1;i<=n-1;i++){
        a=read();b=read();c=read();dis[a][b]=dis[b][a]=c;
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                if(dis[i][k]>=inf||dis[k][j]>=inf)continue;
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                if(dis[i][j]>maxx){
                    maxx=dis[i][j];
                    mxi=i;mxj=j;
                }
            }
    int ans=inf;
    for(int i=1;i<=n;i++){
        if(dis[mxi][i]+dis[i][mxj]!=dis[mxi][mxj])continue;
        for(int j=1;j<=n;j++){
            if(dis[mxi][j]+dis[j][mxj]!=dis[mxi][mxj]||dis[i][j]>s)continue;
            int ecc=0;
            ecc=max(min(dis[mxi][i],dis[mxi][j]),min(dis[mxj][i],dis[mxj][j]));
            ans=min(ans,ecc);
        }
    }
    printf("%d",ans);
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值