思路:
首先一眼dfs序,转化成序列问题来解决这是没有问题的
但是我在如何求徒弟中武功比他高的时候纠结好久。。。其实是我在dfs序中编的号和他给的武功等级让我很混乱了///
这里就运用了树状数组求逆序对的那种思想,我从武功最高的人开始(等级为1的)先看他徒弟的整个区间内是否为0,为0就代表徒弟武功都没他高,然后在把他对应的编号+1(因为我们是按照武功等级来访问的,所以如果访问师父时不为0,就说明前面访问的有他的徒弟,即武功比他高)
#include<bits/stdc++.h> #define pb push_back using namespace std; const int maxn = 1e5+5; int in[maxn],out[maxn],cnt; int s[maxn]; int n,p; vector<int>vt[maxn]; int lowbit(int x) { return x & -x; } void add(int x,int num) { while(x < maxn) { s[x] += num; x += lowbit(x); } return ; } int sum(int x) { int res = 0; while(x) { res += s[x]; x -= lowbit(x); } return res; } void dfs(int x,int f) { in[x] = ++cnt; for(int i = 0;i < vt[x].size();++i) { int v = vt[x][i]; if(v == f) continue; dfs(v,x); } out[x] = cnt; return ; } int main() { while(~scanf("%d %d",&n,&p)) { for(int i = 0;i <= n;++i) vt[i].clear(); for(int i = 1;i < n;++i) { int u,v; scanf("%d %d",&u,&v); vt[u].pb(v); vt[v].pb(u); } cnt = 0; dfs(p,-1); for(int i = 1;i <= n;++i) { int ans = sum(out[i]) - sum(in[i] - 1); printf("%d%c",ans,i == n?'\n':' '); add(in[i],1); } } return 0; }