多画图多画图多画图!
发现输出的都是以k为根的叶子节点。
1.先按以k为根,进行dfs处理。
2.按照节点深度及编号对节点排序,深度越大排序越靠前,深度相同时,编号小的排在前面。
3.依次处理每个节点 ,每次向上蹦,如果碰到以走过的节点或根节点就停止,记录走过的步数。
4.按照走过的步数及编号,对节点做第二次排序,得到的结果即为答案。
这道题中的顺序很关键
然后查bug的时候发现,二维排序的时候要记得把关键字一条条列出来......
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int n,fr; const int N=5e4+3; int tot,head[N]; int ev[N<<1],enx[N<<1]; void add(int u,int v) { ev[++tot]=v,enx[tot]=head[u],head[u]=tot; ev[++tot]=u,enx[tot]=head[v],head[v]=tot; } int dep[N],fa[N]; void dfs(int rt,int f) { fa[rt]=f; dep[rt]=dep[f]+1; for(int i=head[rt];i;i=enx[i]) if(ev[i]!=f) dfs(ev[i],rt); } int stp[N]; bool vis[N]; void count(int rt,int st) { stp[st]++; vis[rt]=true; if(fa[rt] && !vis[fa[rt]] ) count(fa[rt],st); } bool cmp1(int a,int b) { return dep[a]!=dep[b] ?dep[a]>dep[b] :a<b ; } bool cmp2(int a,int b) { return stp[a]!=stp[b] ?stp[a]>stp[b] :a<b ; } int xl[N]; int main() { scanf("%d%d",&n,&fr); printf("%d ",fr++); int x; xl[1]=1; for(int i=2;i<=n;i++) { scanf("%d",&x); add(x+1,i); xl[i]=i; } dfs(fr,0); sort(xl+1,xl+n+1,cmp1); for(int i=1;i<n;i++) { if(vis[xl[i]]) continue; count(xl[i],xl[i]); } sort(xl+1,xl+n+1,cmp2); for(int i=1;i<=n;i++) if(stp[xl[i]]) printf("%d ",xl[i]-1); else break; return 0; }