题面

这道题明显的一定要找到直径的具体路径,所以两遍dfs是比较好的选择;

第一问是一道弱智题吧?

主要难度全部分摊在了第二问;

其实不难,先找到任意一个直径;

对于任意一个在直径上的点:

设nxt[i]表示这个点的下一个位置,pre[i]表示这个点的上一个位置;

ls[i]表示这个点到直径的左端点的距离,rs[i]则表示这个点到直径的右端点的距离;

我们再dfs一遍,找到每个点在不经过直径上任意点的时候所能到达的最远处,这个值记为dismax[i];

那么我们从直径的左端点开始向右推进,直到找到一个点的rs[i]=dismax[i](这意味着存在一条直径使得下一条边不是必经边);

我们注意到,从右向左也需要这么做一次。毕竟我们无法保证从左端点开始就是必经边;

然后就可以A掉了;

#include <bits/stdc++.h>
#define int long long
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
const int MXR=2e5+10;
int head[MXR],cnt;
class littlestar{
public:
int to,nxt,w;
void add(int u,int v,int gg){
to=v; nxt=head[u];
w=gg;head[u]=cnt;
}
}star[MXR<<1];
int n,m;
template<class nT>
void read(nT& x)
{
char c;while(c=getchar(),!isdigit(c));
x=c^48;while(c=getchar(),isdigit(c)) x=x*10+c-48;
}
int dis[MXR],root1,root2,f[MXR],g[MXR];
void dfs(int u,int fa)
{
f[u]=fa;
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==fa) continue;
dis[v]=dis[u]+star[i].w;
dfs(v,u);
g[v]=star[i].w;
}
}
int judge[MXR],ls[MXR],rs[MXR],nxt[MXR],pre[MXR];
int dismax[MXR];
void dfs2(int u,int fa)
{
for(int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(v==fa) continue;
dfs2(v,u);
if(judge[v]==0){
dismax[u]=max(dismax[u],star[i].w+dismax[v]);
}
}
}
signed main()
{
read(n);
inc(i,1,n-1){
int a,b,c;
read(a);read(b);read(c);
star[++cnt].add(a,b,c);
star[++cnt].add(b,a,c);
}
root1=1;
dfs(root1,0);
int maxn=-INT_MAX;
inc(i,1,n) if(dis[i]>maxn) maxn=dis[i],root2=i;
memset(dis,0,sizeof(dis)); maxn=-INT_MAX; memset(f,0,sizeof(f));
dfs(root2,0);
inc(i,1,n) if(dis[i]>maxn) maxn=dis[i],root1=i;
int tmpx=root1;
while(tmpx!=root2){
nxt[tmpx]=f[tmpx];
pre[f[tmpx]]=tmpx;
ls[f[tmpx]]=ls[tmpx]+g[tmpx];
rs[tmpx]=maxn-ls[tmpx];
judge[tmpx]=1;
tmpx=f[tmpx];
}
judge[root2]=1;
dfs2(root2,0);
int goal=0;
tmpx=root1;
while(tmpx!=0){
if(rs[tmpx]==dismax[tmpx]){
break;
}
tmpx=nxt[tmpx];
}
if(tmpx==0) tmpx=pre[tmpx];
goal=tmpx;
while(tmpx!=0){
if(ls[tmpx]==dismax[tmpx]){
break;
}
tmpx=pre[tmpx];
}
if(tmpx==0) tmpx=nxt[tmpx];
int ans=0;
while(tmpx!=goal){
++ans;
tmpx=nxt[tmpx];
}
cout<<maxn<<endl;
cout<<ans; }
/*
6
3 1 1000
1 4 10
4 2 100
4 5 50
4 6 100
*/

[SDOI2013]直径 题解的更多相关文章

  1. Bzoj 3124: [Sdoi2013]直径 题解

    3124: [Sdoi2013]直径 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1222  Solved: 580[Submit][Status] ...

  2. bzoj3124: [Sdoi2013]直径 树形dp two points

    题目链接 bzoj3124: [Sdoi2013]直径 题解 发现所有直径都经过的边 一定在一条直径上,并且是连续的 在一条直径上找这段区间的两个就好了 代码 #include<map> ...

  3. [洛谷P3304] [SDOI2013]直径

    洛谷题目链接:[SDOI2013]直径 题目描述 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅 ...

  4. 【BZOJ3124】[Sdoi2013]直径 树形DP(不用结论)

    [BZOJ3124][Sdoi2013]直径 Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节 ...

  5. bzoj千题计划134:bzoj3124: [Sdoi2013]直径

    http://www.lydsy.com/JudgeOnline/problem.php?id=3124 第一问: dfs1.dfs2 dfs2中记录dis[i]表示点i距离最长链左端点的距离 第二问 ...

  6. 3124: [Sdoi2013]直径

    3124: [Sdoi2013]直径 https://www.lydsy.com/JudgeOnline/problem.php?id=3124 分析: 所有直径都经过的边,一定都是连续的一段.(画个 ...

  7. BZOJ_3124_[Sdoi2013]直径_树形DP

    BZOJ_3124_[Sdoi2013]直径_树形DP Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵 ...

  8. [bzoj3124] [Sdoi2013]直径

    看了child学长的题解才知道怎么写TAT http://www.cnblogs.com/ctlchild/p/5160272.html 以前不知道直径都是过重心的..代码改着改着就和标程完全一样了Q ...

  9. SDOI2013直径(树的直径)

    题目描述: 点这里 题目大意: 就是在一个树上找其直径的长度是多少,以及有多少条边满足所有的直径都经过该边. 题解: 首先,第一问很好求,两边dfs就行了,第一次从任一点找距它最远的点,再从这个点找距 ...

随机推荐

  1. jupyter同时使用python2、3

    jupyter同时使用python2.3 安装ipykernel pip install ipykernel #进入到相应的环境(虚拟环境),运行: 2 python -m ipykernel ins ...

  2. P2699 【数学1】小浩的幂次运算

    原题链接 https://www.luogu.org/problemnew/show/P2699 P2699 [数学1]小浩的幂次运算 首先第一眼看这个题就知道要暴力枚举w^i 看是否在区间[l,r] ...

  3. AtCoder AGC001E BBQ Hard (DP、组合计数)

    题目链接: https://atcoder.jp/contests/agc001/tasks/agc001_e 题解: 求\(\sum^n_{i=1}\sum^n_{j=i+1} {A_i+A_j+B ...

  4. 预处理、const、static、sizeof-说明内联函数使用的场合

    1:首先使用inline函数可以完全取代表达式形式的宏定义. 内联函数在C++类中的应用最广的应该是用来定义存取函数.我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们 ...

  5. spring boot通过自定义注解和AOP拦截指定的请求

    一 准备工作 1.1 添加依赖 通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截 <dependency> <group ...

  6. Elasticsearch6.5.1破解x-pack,设置密码并使用head插件登陆。

    #没有许可证的es无法持久的设置密码,而且使用一段时间后会过期,过期后,一些功能无法被使用,例如head插件无法看到es状态. 下图是过期的es的状态,可通过此url查看:http://ip:port ...

  7. react数据渲染

    现在需要在页面上显示一本书的章节,章节内容存放到一个数组里面: const lessons = [ { title: 'Lesson 1: title', description: 'Lesson 1 ...

  8. Go语言fmt.Printf使用指南(占位符总结)

    本文整理了Go语言的标准输出流(fmt.Printf)在打印到屏幕时的格式化输出操作. 在这里按照占位符将被替换的变量类型划分,更方便查询和记忆. 总结 1.1 General(通用占位符) 占位符 ...

  9. [转]Nginx配置信息详解

    序言 Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭借开源的力量,已经接近成熟与完善. Nginx功能丰富,可作为HTTP服务器,也 ...

  10. Android:通过systrace进行性能分析

    一.Systrace 简介 Systrace 允许您在系统级别(如SurfaceFlinger.WindowManagerService等Framework部分关键模块.服务.View系统等)收集和检 ...