Codeforces Round #253 (Div. 1)D题

D. Adam and Tree
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

When Adam gets a rooted tree (connected non-directed graph without cycles), he immediately starts coloring it. More formally, he assigns a color to each edge of the tree so that it meets the following two conditions:

  • There is no vertex that has more than two incident edges painted the same color.
  • For any two vertexes that have incident edges painted the same color (say, c), the path between them consists of the edges of the color c.

Not all tree paintings are equally good for Adam. Let's consider the path from some vertex to the root. Let's call the number of distinct colors on this path the cost of the vertex. The cost of the tree's coloring will be the maximum cost among all the vertexes. Help Adam determine the minimum possible cost of painting the tree.

Initially, Adam's tree consists of a single vertex that has number one and is the root. In one move Adam adds a new vertex to the already existing one, the new vertex gets the number equal to the minimum positive available integer. After each operation you need to calculate the minimum cost of coloring the resulting tree.

Input

The first line contains integer n (1 ≤ n ≤ 106) — the number of times a new vertex is added. The second line contains n numbers pi (1 ≤ pi ≤ i) — the numbers of the vertexes to which we add another vertex.

Output

Print n integers — the minimum costs of the tree painting after each addition.

Sample test(s)
input
11
1 1 1 3 4 4 7 3 7 6 6
output
1 1 1 1 1 2 2 2 2 2 3 
Note

The figure below shows one of the possible variants to paint a tree from the sample at the last moment. The cost of the vertexes with numbers 11 and 12 equals 3.



题意:给定N个结点,每次输入该结点的父亲标号,问你到现在为止这颗树所用的最大颜色花费最少是多少,树的最大颜色花费规定为所有结点到根结点路径上的颜色种类数量最大的那个值,涂色有三种规定,1.每条边都可以涂任意一种颜色,2.如果任意两个结点有边涂相同的颜色,那么这两个结点路径上所有边都要涂成这种颜色,3.对于任意结点所连的同一种颜色的边不能超过两条.
     思路:乍一看真心觉得复杂,但仔细想想,画出这棵树发现对于一条枝可以一种颜色涂到底,如果该枝干上出现分枝则该分枝必须换一种颜色往下涂,以此类推,实际上这样就可以从叶子节点往上递推,因为当以某个节点为根的树算出答案以后,就可以继续往上跟新父亲的答案了,只需要维护2个数组,ww[i]表示以i的父亲为根的最大花费,ca[i]表示以i为根的最大花费,这样每次往上跟新只需判断ww[father]


#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
using namespace std;
#define maxn 1000100

int fa[maxn];
int ca[maxn];
int ww[maxn];

int maxi(int x,int y)
{
    return x>y?x:y;
}

int main()
{
    int n,i,f,c;

    while(scanf("%d",&n)!=EOF)
    {
        memset(ca,0,sizeof(ca));
        for(i=1;i<=n+1;i++)ww[i]=1;

        int ansm=1;

        for(i=2;i<=n+1;i++)
        {
            scanf("%d",&f);
            c=i;
            fa[c]=f;
      //      printf("\n");
     //       printf("%d %d %d %d %d\n",ww[f],ca[f],c,ww[c],ca[4]);
            while(f!=1&&((ww[f]
            {
                    ca[f]=maxi(ww[c],ca[f]);
                    ww[f]++;
                    c=f;
                    f=fa[c];
            }

            ca[f]=maxi(ww[c],ca[f]);

            if(f==1&&ansm
            //printf("%d %d ",f,ca[f]);
            printf("%d",ansm);
            if(i!=n+1)printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

      
      
     
     
    
    
   
   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值