前言
简单题。
题目大意
若干轮比赛,每个人在某一轮可以参赛,和另外一个人pk,输的人淘汰。
最后1是冠军,已知其余每个人输给了谁,请问最少设置多少轮比赛?
做法
你显然可以根据每个人输给了谁建一颗树,然后处理f[x]表示x淘汰所有输给他的人所需要的最小轮数。
转移很简单,根据儿子的f排序,然后详见代码(不会说)。
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=100000+10;
int f[maxn],a[maxn],h[maxn],go[maxn],nxt[maxn];
int i,j,k,l,t,n,m,tot,top;
void add(int x,int y){
go[++tot]=y;
nxt[tot]=h[x];
h[x]=tot;
}
void dfs(int x){
int t=h[x];
if (!t) return;
while (t){
dfs(go[t]);
t=nxt[t];
}
top=0;
t=h[x];
while (t){
a[++top]=f[go[t]];
t=nxt[t];
}
sort(a+1,a+top+1);
int i;
fo(i,2,top)
if (a[i]<=a[i-1]) a[i]=a[i-1]+1;
f[x]=a[top]+1;
}
int main(){
scanf("%d",&n);
fo(i,2,n){
scanf("%d",&j);
add(j,i);
}
dfs(1);
printf("%d\n",f[1]);
}