先画画图:
右边是6的原因是,要满足6位置的点和3位置的点距离>=3。
从这里可以发现,如果存在多个子链,那么下一条子链的第一个权值=上一条子链最后一个权值+回溯链长。
为了使得回溯链长总和最小,容易想到将最长的链放到最后赋值。
具体做法是先找到树的直径,然后从直径的一端点开始赋值,先对非直径赋值,再对直径赋值,
回溯的时候赋值用的tot++,因为要加上回溯链长。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
vector<int>g[maxm];
int dep[maxm],son[maxm];
int ans[maxm];
int n;
void dfs1(int x,int fa){dep[x]=dep[fa]+1;for(int v:g[x]){if(v==fa)continue;dfs1(v,x);}
}
void dfs2(int x,int fa){dep[x]=0;for(int v:g[x]){if(v==fa)continue;dfs2(v,x);dep[x]=max(dep[x],dep[v]+1);if(dep[v]>dep[son[x]]){son[x]=v;}}
}
int tot=0;
void dfs3(int x,int fa){ans[x]=++tot;for(int v:g[x]){if(v==fa||v==son[x])continue;dfs3(v,x);}if(son[x]){dfs3(son[x],x);}tot++;//回溯的时候要加上回溯链的长度.
}
void solve(){cin>>n;for(int i=1;i<n;i++){int a,b;cin>>a>>b;g[a].push_back(b);g[b].push_back(a);}//找直径的一端dfs1(1,1);int ma=1;for(int i=1;i<=n;i++){if(dep[i]>dep[ma]){ma=i;}}dfs2(ma,ma);//计算长短儿子//dfs3(ma,ma);//计算答案//for(int i=1;i<=n;i++){cout<<ans[i]<<' ';}cout<<endl;
}
signed main(){ios::sync_with_stdio(0);solve();return 0;
}
本文发布于:2024-02-03 04:11:02,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170690466348565.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |