10.02 T2 树上DP

Description

2.1 题目背景
银企鹅非常擅长化学。有一天他在试图命名一个巨大的单烯烃分子的时候,想到了一个问题。
2.2 题目描述
给你一棵树,一些边有标记,对于每条有标记的边,在树中找到包含这条边的一条最长链,并输出长度。

Input

第一行一个整数 id 表示测试点的编号。
多组数据,第二行一个整数 T 表示数据组数。
对于每组数据,第一行两个整数 n,m 表示节点的个数,和被标记的边的个数。
我们规定 1 是根,第二行 n − 1 个整数给出 2 ∼ n 父亲的编号,保证f(ai) < i。
第三行 m 个整数范围在 [2,n] 表示哪个点的父边被标记过。

Output

对于每组数据输出一行 m 个整数,必须与输入的边顺序一致,给出的是在这条边必选的情况下树中最长链的长度。

Sample Input

0 1 10 3 1 2 3 1 4 6 7 3 8 10 7 9

Sample Output

8 8 6

Hint

Source

root
 
 
 
一道很裸的树形DP,可惜我求了直径就直接爆炸了
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define N 1000005
 5 using namespace std;
 6 struct node{
 7     int u,v;
 8 }e[N];
 9 int first[N],nxt[N],cnt,u[N],d1[N],d2[N],fa[N],c1[N],c2[N];
10 void add(int u,int v){
11     e[++cnt].u=u;
12     e[cnt].v=v;
13     nxt[cnt]=first[u];
14     first[u]=cnt;
15 }
16 void dfs1(int x){
17     for(int i=first[x];i;i=nxt[i]){
18         int v=e[i].v;
19         if(v==fa[x])continue;
20         dfs1(v);
21         if(d1[v]+1>d1[x]){
22             d2[x]=d1[x];
23             d1[x]=d1[v]+1;
24             c1[x]=v;
25         }
26         else {
27             d2[x]=max(d2[x],d1[v]+1);
28         }
29     }
30 }
31 void dfs2(int x){
32     if(fa[x]){//父亲不是1 
33         if(c1[fa[x]]==x){
34             u[x]=max(u[fa[x]],d2[fa[x]])+1;// 父亲向上的最大值和父亲的次大值 
35         }
36         else u[x]=max(u[fa[x]],d1[fa[x]])+1;//否则肯定就是父亲向下的最大值,当然还要加上1 
37     }
38     for(int i=first[x];i;i=nxt[i]){
39         int v=e[i].v;
40         if(v==fa[x])continue;
41         dfs2(v);
42     }
43 }
44 void init(){
45     memset(e,0,sizeof e);
46     memset(first,0,sizeof first);
47     memset(nxt,0,sizeof nxt);
48     cnt=0;
49     memset(u,0,sizeof u);
50     memset(d1,0,sizeof d1);
51     memset(d2,0,sizeof d2);
52     memset(c1,0,sizeof c1);
53 }
54 inline int Get(){
55     register int rec=0;
56     register char c;
57     register bool f=0;
58     for(c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=true;
59     while(c>='0'&&c<='9'){
60         rec=(rec<<3)+(rec<<1)+c-'0';
61         c=getchar();
62     }
63     return f?(-rec):rec;
64 }
65 int main(){
66 //    freopen("olefin.in","r",stdin);
67     //freopen("olefin.out","w",stdout);
68     int id;
69     cin>>id;
70     int T;
71     T=Get();
72     while(T--){
73         init();
74         int n,m;
75         n=Get();m=Get();
76         for(int i=2;i<=n;i++){
77             fa[i]=Get();
78             add(i,fa[i]);
79             add(fa[i],i);
80         }
81         dfs1(1);
82         dfs2(1);
83         for(int i=1;i<=m;i++){
84             int x;x=Get();
85             cout<<d1[x]+u[x]<<" ";
86         }
87         if(m)cout<<'\n';
88     }
89     return 0;
90 }

over

posted @ 2018-10-03 08:22  saionjisekai  阅读(53)  评论(0编辑  收藏  举报