D48 树的直径 P3304 [SDOI2013] 直径
视频链接:D48 树的直径 P3304 [SDOI2013] 直径_哔哩哔哩_bilibili
P3304 [SDOI2013] 直径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
// 两次 DFS O(n) #include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N=200005; struct edge{ int to,w,ne; }e[N<<1]; int head[N],idx; void add(int x,int y,int w){ e[++idx]={y,w,head[x]}; head[x]=idx; } int n,p,l,r,cnt,fa[N],col[N]; ll d[N],mxd; 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",&n); for(int i=1,x,y,z;i<n;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs(1,0); d[p]=0; l=p; dfs(p,0); mxd=d[p]; r=p; printf("%lld\n",mxd); for(int i=r;i;i=fa[i])col[i]=1; //直径染色 for(int i=r;i;i=fa[i]){ ll ld=d[i],rd=mxd-d[i]; p=i,d[i]=0; dfs(i,fa[i]); if(d[p]==rd) r=i; if(d[p]==ld){l=i;break;} } //区间[l,r]为公共路径 for(int i=r;i!=l;i=fa[i]) cnt++; printf("%d\n",cnt); }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步