2 条题解
-
0
树的直径,几乎板子题,用一遍dfs找寻起始点和长度,两次dfs建立重链,LCA求出起始点最近公共祖先,往上枚举,输出,完事。
注意:十年OI一场空,____________。
AC 代码
#include<bits/stdc++.h> #define int long long using namespace std; const int N=5e5+10; vector<pair<int,int> >G[N]; int d[N],d2[N],n,ans,st,ed,s[N],s2[N]; //d表示当前节点往下的最长路径长度,s存储终点 //d2和s2表示次长路径 //ans,st,ed存储全树最长路径及其起始点 int son[N],siz[N],tp[N],fa[N],dep[N]; void dfs(int x,int xfa,int dis)//找寻直径长度并存储起始点 { s[x]=s2[x]=x; for(auto i:G[x])if(i.first!=xfa) { dfs(i.first,x,dis+i.second); int t=d[i.first]+i.second; if(t>d[x])d2[x]=d[x],s2[x]=s[x],d[x]=t,s[x]=s[i.first]; else if(t>d2[x])d2[x]=t,s2[x]=s[i.first];//更新 } if(d[x]+d2[x]>ans)ans=d[x]+d2[x],st=s[x],ed=s2[x]; if(d[x]+dis>ans)ans=d[x]+dis,st=s[x],ed=1;//不要忘记往上的路径长度 } void dfs1(int x,int xfa)//重链LCA { siz[x]=1;son[x]=-1;fa[x]=xfa;dep[x]=dep[xfa]+1; for(auto i:G[x])if(i.first!=xfa) { dfs1(i.first,x); siz[x]+=siz[i.first]; if(siz[i.first]>siz[son[x]]||son[x]==-1)son[x]=i.first; } } void dfs2(int x,int top) { tp[x]=top; if(son[x]!=-1)dfs2(son[x],top); for(auto i:G[x])if(i.first!=fa[x]&&i.first!=son[x])dfs2(i.first,i.first); } int LCA(int x,int y) { for(;tp[x]!=tp[y];x=fa[tp[x]])if(dep[tp[x]]<dep[tp[y]])swap(x,y); return dep[x]<dep[y]?x:y; } signed main() { scanf("%lld",&n); for(int i=1,x,y,w;i<n;i++) { scanf("%lld%lld%lld",&x,&y,&w);x++,y++; G[x].push_back({y,w}); G[y].push_back({x,w}); } dfs(1,0,0); printf("%lld ",ans); dfs1(1,0);dfs2(1,1); int lca=LCA(st,ed); vector<int>up1,up2;//记录答案 for(;st!=lca;st=fa[st])up1.push_back(st); up1.push_back(lca);//不能忘lca for(;ed!=lca;ed=fa[ed])up2.push_back(ed); reverse(up2.begin(),up2.end());//反过来才是答案 printf("%lld\n",up1.size()+up2.size()); for(int i:up1)printf("%lld ",i-1); for(int i:up2)printf("%lld ",i-1);//输出 return 0;//完结撒花 } -
0
#include<bits/stdc++.h> using namespace std; const int N=5e5+10; #define int long long #define PII pair<int,int> #define fi first #define se second int mx[N],mx1[N],mx2[N],son1[N],son2[N],rt[N]; vector<PII>G[N]; void dfs(int x,int f) { for(auto i:G[x])if(i.fi!=f) { int y=i.fi,w=i.se; dfs(y,x); if(mx1[x]<mx1[y]+w) mx2[x]=mx1[x],mx1[x]=mx1[y]+w,son2[x]=son1[x],son1[x]=y; else if(mx2[x]<mx1[y]+w) mx2[x]=mx1[y]+w,son2[x]=y; if(mx[x]<mx[y]) mx[x]=mx[y],rt[x]=rt[y]; } if(mx[x]<=mx1[x]+mx2[x]) mx[x]=mx1[x]+mx2[x],rt[x]=x; } deque<int>q; void dfs1(int x) { q.push_back(x); if(son1[x])dfs1(son1[x]); } void dfs2(int x) { if(son1[x])dfs2(son1[x]); q.push_back(x); } void output(int x) { cout<<mx[x]<<' '; if(son1[x])dfs2(son1[x]); q.push_back(x); if(son2[x])dfs1(son2[x]); cout<<q.size()<<'\n'; for(int i:q)cout<<i-1<<' '; } signed main() { int n;cin>>n; for(int i=1;i<n;i++) { int x,y,w;cin>>x>>y>>w;x++,y++; G[x].push_back({y,w}); G[y].push_back({x,w}); } dfs(1,0); output(rt[1]); return 0; }
- 1
信息
- ID
- 8195
- 时间
- 500ms
- 内存
- 1024MiB
- 难度
- 5
- 标签
- 递交数
- 25
- 已通过
- 13
- 上传者