原题链接

题目描述

共两个问题,第一问求树的直径长度,第二问求直径的必须边


思路

第一问很好求,lyd书里有,就不再赘述。

这里建议使用两次bfs的方法,因为关系到第二问的路径,这么做比较方便。

然后考虑第二问。

(注:必须边就是每条直径都要经过的一部分边)

容易知道,所有必须边构成一条链(有待证明)(其实是懒得想2333)

假设现在已经求得了一条直径的具体路径。设其两端分别为x和y。

从一端枚举到另外一端,并用l和r维护相交的部分。

先看x到y的。

设当前的节点为u。如果(u和x的距离)==(u不过直径能达到的最大长度),

说明u这里是直径的分叉口,\(l=u\)

再看y到x的。

同样的道理,若(u和y的距离)==(u不过直径的最大长度),\(r=u\)

这样就确定了 l 和 r,完成!

(ps:记得开long long哦)


C++ 代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int n,tot=0,head[N],rt1,rt2,q[N],h,t,fro[N],hh[N];
bool vis[N];ll dis[N];
struct edge
{
int ver,nxt;
ll w;
}e[N*2]; void mmax( ll &x,ll y )
{
if ( y>x ) x=y;
} void bfs( int st )
{
memset( vis,0,sizeof(vis) );
dis[st]=0; vis[st]=1; h=1; t=0; q[++t]=st;
while ( h<=t )
{
int x=q[h++];
for ( int i=head[x]; i; i=e[i].nxt )
{
int to=e[i].ver;
if ( vis[to] ) continue;
dis[to]=dis[x]+e[i].w; vis[to]=1; fro[to]=x;
q[++t]=to;
}
}
} ll dfs( int x,int fa )
{
if ( fa!=0 && vis[x] ) return 0;
ll s=0;
for ( int i=head[x]; i; i=e[i].nxt )
{
int to=e[i].ver;
if ( to==fa || vis[to] ) continue;
mmax( s,dfs( to,x )+e[i].w );
}
return s;
} void add( int u,int v,ll w )
{
tot++; e[tot].nxt=head[u]; e[tot].w=w; e[tot].ver=v; head[u]=tot;
} int main()
{
scanf( "%d",&n );
for ( int i=1,x,y,l; i<n; i++ )
{
scanf( "%d%d%d",&x,&y,&l );
add( x,y,l ); add( y,x,l );
} ll s=0; int x,l,r;
bfs( 1 );
for ( int i=1; i<=n; i++ )
if ( s<dis[i] ) s=dis[i],rt1=i;
bfs( rt1 ); s=0;
for ( int i=1; i<=n; i++ )
if ( s<dis[i] ) s=dis[i],rt2=i;
memset( vis,0,sizeof(vis) );
x=rt2; vis[rt1]=1;
while ( x!=rt1 )
{
vis[x]=1; hh[fro[x]]=hh[x]+1; x=fro[x];
}
l=rt2; r=rt1; x=rt2;
while ( x!=rt1 )
{
s=dfs( x,0 );
if ( s==dis[rt2]-dis[x] ) l=x;
if ( s==dis[x] )
{
r=x; break;
}
x=fro[x];
} printf( "%lld\n%d",dis[rt2],hh[r]-hh[l] );
}

运行总时间:455ms 空间:15456 KB

完结撒花qwq

update

我找到证明了qwq

夏日大佬的一句话完结。

“显然直径的必须边一定连续,不然就成环了”

夏日大佬tql orz


其实还有一种更为优美的做法。这里空间很大,我就写一下吧(

可以发现,直径的公共部分,一定是连在一起的。那么可以在第一问的时候求出直径长度,并把所有直径上的边权减一,然后再求一次直径,两次的差就是答案。

原因显然。

【题解】AcWing 389. 直径的更多相关文章

  1. REHの收藏列表

    搬运自本人的AcWing,所以那里的文章会挺多. 友链(同类文章) :bztMinamoto 世外明月 mlystdcall 新人手册:AcWing入门使用指南 前言 有看到好文欢迎推荐(毛遂自荐也可 ...

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

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

  3. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  4. 一些noip模拟题一句话题解

    Problem A: 序列 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 12  Solved: 9[Submit][Status][Web Boar ...

  5. 【bzoj2870】最长道路tree 树的直径+并查集

    题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...

  6. 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列

    题目描述 给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值.求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小. 输入 包含n行: 第1行,两个正整数n和s ...

  7. AcWing 91. 最短Hamilton路径

    今天第一次在\(AcWing\)这个网站上做题,来发一下此网站的第一篇题解 传送门 思路 直接枚举的话时间复杂度为\(O(n*n!)\) 复杂度显然爆炸,所以我们用二进制枚举,这样就可以把复杂度降到\ ...

  8. (acwing蓝桥杯c++AB组)1.2 递推

    1.2 递推与递归 文章目录 1.2 递推与递归 位运算相关知识补充 pair与vector相关知识补充 题目目录与网址链接 下面的讲解主要针对这道题目的题解AcWing 116. 飞行员兄弟 - A ...

  9. 2014 牡丹江区域赛 B D I

    http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=358 The 2014 ACM-ICPC Asia Mudanj ...

随机推荐

  1. nginx&http 第三章 ngx 事件event accept epoll /init

    tcp 三次握手成功后,listen fd  可读,在process_event_timer 中调用rev->handler(rev)处理: 其回调函数为: ngx_event_accept / ...

  2. 汇编语言常用的DOS功能调用

    今天掌握了汇编语言常用的DOS功能调用,现在列出来供参考. 1.单字符输入(1号调用) 格式:MOV AH,1 INT 21H 功能:达到输入状态,从键盘上输入字符的ASCII码送入AX中,并送显示器 ...

  3. Weblogic CVE-2020-2551漏洞复现&CS实战利用

    Weblogic CVE-2020-2551漏洞复现 Weblogic IIOP 反序列化 漏洞原理 https://www.anquanke.com/post/id/199227#h3-7 http ...

  4. MySQL错误修复:Table xx is marked as crashed and last (automatic?) repair failed

    问题一 Table xx is marked as crashed and last (automatic?) repair failed 有开发找到我,说数据库坏了,连不上数据库,看了下 MySQL ...

  5. vue项目中echarts属性总结

    <div id="echarts" style="width: 600px;height: 400px;margin-top: 100px;margin-left: ...

  6. ceph 集群快速部署

    1.三台Centos7的主机 [root@ceph-1 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core)    2.主机 ...

  7. python3时间函数

    上一篇是生成测试报告的代码,如果重复运行测试报告名称相同会不停的覆盖,之前的测试报告也会丢失,无法追溯之前的问题.那么如何解决这个问题了呢? 首先想到的是用随机函数取随机名称,一旦生成的报告较多时,无 ...

  8. Flask端点概念

    Flask要点理解 路由端点 通常,我们使用app.route()装饰器将视图函数注册为路由.如果不使用该装饰器,也可以采用app.add_url_rule(rule, endpoint, view_ ...

  9. Java基础教程——结构化编程

    结构化编程 各结构的图示请参见: https://www.cnblogs.com/tigerlion/p/10703926.html 选择结构 |-if:如果 |-else:其他:此外:否则. pub ...

  10. 公平lock和非公平lock的区别

    可以看到区别在于,在lock时和tryAquire时,非公平锁不会去管队列中有没有线程在排队,直接尝试去获取锁,失败之后就和公平锁一样,乖乖去排队. 也就是说发生竞争的场景在于,尚未入队的线程之间和刚 ...