题解:P10921 Happybob's Puzzle (UBC001A)
又是一道欧拉路。
思路
在一个树上,两点
因为这个题只讨论奇偶性,所以求了 lca 也无用。只需要求出深度即可。
然后就会发现:一个奇数深度的要和偶数度数的在一起;一个偶数深度的要和奇数深度的在一起。
考虑图论建模:奇数深度说明后面要接偶数,就是奇数向偶数连边;偶数后面要接奇数,就是偶数向奇数连边。
然后检验这张只由奇偶两个点组成的图中存不存在欧拉路就行。判定方法:设奇数深度点数为
然后就是输出了。我们记录下奇数深度和偶数深度的点并按字典序排序。
- 如果
,则我们比较字典序最小的奇数深度的和偶数深度点,看哪个更小。如果奇数的更小,我们按照奇数至偶数至奇数至偶数的顺序输出;反之是偶数到奇数到偶数。 - 如果
,则必须以奇数开始,按字典序循环输出即可。 - 如果
,与上面的情况类似。
代码
#include<bits/stdc++.h>
using namespace std;
int T,n;
struct edge{
int u,v,nxt;
}e[200005];
int cnt,head[100005],dep[100005],ou[100005],ji[100005],du,cnt1,cnt2;
void add(int u,int v){
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
void dfs(int now,int fa,int d){
dep[now]=d;
for(int i=head[now];i;i=e[i].nxt){
if(e[i].v==fa)continue;
dfs(e[i].v,now,d+1);
}
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(head,0,sizeof(head));
cnt=0;
memset(e,0,sizeof(e));
memset(ji,0,sizeof(ji));
cnt1=0;
cnt2=0;
memset(ou,0,sizeof(ou));
memset(dep,0,sizeof(dep));
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(1,1,1);
for(int i=1;i<=n;i++){
if(dep[i]&1){
ji[++cnt1]=i;
}
else{
ou[++cnt2]=i;
}
}
if(cnt1-cnt2>1||cnt1-cnt2<-1){
printf("-1\n");
continue;
}
sort(ji+1,ji+cnt1+1);
sort(ou+1,ou+cnt2+1);
if(cnt1==cnt2){
if(ji[1]<ou[1]){
for(int i=1,j=1;i<=cnt1;i++,j++){
printf("%d %d ",ji[i],ou[j]);
}
}
else{
for(int i=1,j=1;i<=cnt1;i++,j++){
printf("%d %d ",ou[j],ji[i]);
}
}
}
else{
if(cnt1==cnt2+1){
printf("%d ",ji[1]);
for(int i=2,j=1;i<=cnt1;i++,j++){
printf("%d %d ",ou[j],ji[i]);
}
}
else{
printf("%d ",ou[1]);
for(int i=2,j=1;i<=cnt2;i++,j++){
printf("%d %d ",ji[j],ou[i]);
}
}
}
printf("\n");
}
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】