10.21模拟赛 猴猴吃苹果(排序)
满分做法:
手画样例,发现输出的都是以k为根的叶子节点。于是我们按照以下步骤去操作即可:
1.先按以k为根,进行dfs处理。
2.按照节点深度及编号对节点排序,深度越大排序越靠前,深度相同时,编号小的排在前面。
3.依次处理每个节点 ,每次向上蹦,如果碰到以走过的节点或根节点就停止,记录走过的步数。
4.按照走过的步数及编号,对节点做第二次排序,得到的结果即为答案。
#include<cstring> #include<queue> #include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<vector> using namespace std; const int maxm=100007; int n,k; int pre[maxm],last[maxm],other[maxm],l; bool vis[maxm]; int tot; int f[maxm]; struct node { int id,dep; }a[maxm]; struct srt { int id,ans; }t[maxm]; bool cmp(node a,node b) { if(a.dep==b.dep) return a.id<b.id; return a.dep>b.dep; } bool cmp1(srt a,srt b) { if(a.ans==b.ans) return a.id<b.id; return a.ans>b.ans; } void add(int x,int y) { l++; pre[l]=last[x]; last[x]=l; other[l]=y; } void dfs(int x) { for(int p=last[x];p;p=pre[p]) { int v=other[p]; if(vis[v]) continue; f[v]=x; vis[v]=1; a[v].dep=a[x].dep+1; a[v].id=v; dfs(v); } } int work(int x) { int tmp=0; while(!vis[x]) { vis[x]=1; x=f[x]; tmp++; } return tmp; } int main() { freopen("apple.in","r",stdin); freopen("apple.out","w",stdout); scanf("%d%d",&n,&k); for(int i=1;i<=n-1;i++) { int x; scanf("%d",&x); add(i,x); add(x,i); } a[k].id=k; a[k].dep=1; vis[k]=1; dfs(k); sort(a,a+n,cmp); memset(vis,0,sizeof(vis)); vis[k]=1; printf("%d\n",k); for(int i=0;i<n;i++) { if(vis[a[i].id]) continue; else { t[++tot].ans=work(a[i].id); t[tot].id=a[i].id; } } sort(t+1,t+tot+1,cmp1); for(int i=1;i<=tot;i++) { printf("%d\n",t[i].id); } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 如何打造一个高并发系统?
· 《SpringBoot》EasyExcel实现百万数据的导入导出