【题解】AcWing 389. 直径
题目描述
共两个问题,第一问求树的直径长度,第二问求直径的必须边
思路
第一问很好求,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. 直径的更多相关文章
- REHの收藏列表
搬运自本人的AcWing,所以那里的文章会挺多. 友链(同类文章) :bztMinamoto 世外明月 mlystdcall 新人手册:AcWing入门使用指南 前言 有看到好文欢迎推荐(毛遂自荐也可 ...
- bzoj3124: [Sdoi2013]直径 树形dp two points
题目链接 bzoj3124: [Sdoi2013]直径 题解 发现所有直径都经过的边 一定在一条直径上,并且是连续的 在一条直径上找这段区间的两个就好了 代码 #include<map> ...
- 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...
- 一些noip模拟题一句话题解
Problem A: 序列 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 12 Solved: 9[Submit][Status][Web Boar ...
- 【bzoj2870】最长道路tree 树的直径+并查集
题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...
- 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列
题目描述 给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值.求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小. 输入 包含n行: 第1行,两个正整数n和s ...
- AcWing 91. 最短Hamilton路径
今天第一次在\(AcWing\)这个网站上做题,来发一下此网站的第一篇题解 传送门 思路 直接枚举的话时间复杂度为\(O(n*n!)\) 复杂度显然爆炸,所以我们用二进制枚举,这样就可以把复杂度降到\ ...
- (acwing蓝桥杯c++AB组)1.2 递推
1.2 递推与递归 文章目录 1.2 递推与递归 位运算相关知识补充 pair与vector相关知识补充 题目目录与网址链接 下面的讲解主要针对这道题目的题解AcWing 116. 飞行员兄弟 - A ...
- 2014 牡丹江区域赛 B D I
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=358 The 2014 ACM-ICPC Asia Mudanj ...
随机推荐
- wireguard使用
1.编译与安装 sudo apt-get install libmnl-dev libelf-dev linux-headers-$(uname -r) build-essential pkg-con ...
- python之路 《六》函数
---恢复内容开始--- 为什么要有函数? 当你的老板要你写一个程序 1 def 函数0(): 2 # 如果cpu占用率>90 3 # 发送邮件 4 # 发出警报 5 6 def 函数1(): ...
- go-zero之web框架
go-zero 是一个集成了各种工程实践的 web 和 rpc 框架,其中rest是web框架模块,基于Go语言原生的http包进行构建,是一个轻量的,高性能的,功能完整的,简单易用的web框架 服务 ...
- Python_网络编程_socket()
什么是 Socket? Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 详细资 ...
- 分布式监控系统之Zabbix宏、模板和自定义item
前文我们聊了下zabbix的基础使用,包括主机的添加.监控项.触发器.action以及告警通知的配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/140073 ...
- 太湖杯writeup
CheckInGame checkInGame本题是个js游戏 设置个断点后,之后修改时间即可,然后把游戏玩完就行. ezWeb 本题是模板注入,过滤了{}和"",用︷︸和无引号的 ...
- Vegas视频FX功能详解
今天呢,小编就带大家走进Vegas(Win系统)视频FX的世界.那么什么是视频FX呢,就是视频制作软件Vegas中自带添加特效的地方,它可以用于添加模糊,黑白,镜像等滤镜效果,各种高大上的视频大片都需 ...
- python中的unittest库
1.unittest框架是python自动化测试的入门框架,它是python自带的一个模块 包含以下几个子模块 测试用例:TestCase 测试集:TestSuite 加载用例:TestLoader ...
- JPA使用之@Query的常用写法
准备 实体 @Data @Table(name = "task_apply") @Entity public class TaskApply { @Id @GeneratedVal ...
- 【CF600E】Lomsat gelral——树上启发式合并
(题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 裸题.统计时先扫一遍得到出 ...