D49 树的直径 P2491 [SDOI2011] 消防
视频链接:D49 树的直径 P2491 [SDOI2011] 消防_哔哩哔哩_bilibili
P2491 [SDOI2011] 消防 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P1099 [NOIP2007 提高组] 树网的核 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 完全一样
// 两次DFS+双指针 O(n) #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=300010; int idx,head[N]; struct edge{int to,w,ne;}e[N<<1]; void add(int u,int v,int w){ e[++idx]={v,w,head[u]},head[u]=idx; } int n,s,p,r,d[N],fa[N],col[N]; int ans=2e9; void dfs(int x,int ff){ fa[x]=ff; //记录路径 if(d[x]>d[p]) p=x; //更新端点 for(int i=head[x];i;i=e[i].ne){ int y=e[i].to,w=e[i].w; if(y==ff||col[y]) continue; d[y]=d[x]+w; dfs(y,x); } } int main(){ scanf("%d%d",&n,&s); for(int i=1,u,v,w;i<n;i++){ scanf("%d%d%d",&u,&v,&w); add(u,v,w);add(v,u,w); } dfs(1,0); d[p]=0; dfs(p,0); r=p; //直径右端点 for(int i=r,j=r;i;i=fa[i]){ //双指针 while(d[j]-d[i]>s) j=fa[j]; ans=min(ans,max(d[i],d[r]-d[j])); } //直径上的答案 for(int i=r;i;i=fa[i])col[i]=1; //直径染色 for(int i=r;i;i=fa[i]){ p=i;d[i]=0; dfs(i,fa[i]); } //直径外的答案 for(int i=1;i<=n;i++)ans=max(ans,d[i]); printf("%d\n",ans); }
分类:
D 图论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2023-09-16 A40 反悔贪心 P2949 [USACO] Work Scheduling G
2023-09-16 A39 反悔贪心 CF865D Buy Low Sell High