题解:P15875 [ICPC 2026 NAC] Acorn Quarrels
小清新构造题。
题意
给定一棵树,要求给树上每个点赋一个点权
设当前
i 的邻点的点权最大值为k ,对于每一个与i 相连的点u ,若v_u=k ,v_u=v_u-1,v_i=v_i+1 。
Solution
这个限制不太好做,考虑强化一下限制。
我们令
容易发现操作完之后每个位置的点权确实是不变的,因为减了
我们发现这个东西是很好构造的,考虑从根往下递推。
一个点
我们已经知道了当前点
容易发现总能构造出一组解并且
::::success[Code]
int w[N],n,mn=1e9;
vector<int>e[N];
int col(int u,int t){
int res=w[u];
int h=lower_bound(e[u].begin(),e[u].end(),t)-e[u].begin();
if(u>=t)return res-h;
return res-h+e[u].size();
}
int d(int u,int t,int p){
int h=lower_bound(e[u].begin(),e[u].end(),t)-e[u].begin();
if(u>=t)return p+h;
return p-e[u].size()+h;
}
void dfs(int u,int fa){
int h=col(fa,u);
for(auto v : e[u]){
if(v==fa)continue;
w[v]=d(v,u,h);
dfs(v,u);
}
}
int main(){
scanf("%d",&n);
for(int i=1,u,v;i<n;++i){
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;++i)sort(e[i].begin(),e[i].end());
dfs(1,0);
for(int i=1;i<=n;++i)mn=min(mn,w[i]);
mn=n-mn;
for(int i=1;i<=n;++i)printf("%d ",w[i]+mn);
return 0;
}
::::