10.02 T2 树上DP
Description
2.1 题目背景
银企鹅非常擅长化学。有一天他在试图命名一个巨大的单烯烃分子的时候,想到了一个问题。
2.2 题目描述
给你一棵树,一些边有标记,对于每条有标记的边,在树中找到包含这条边的一条最长链,并输出长度。
银企鹅非常擅长化学。有一天他在试图命名一个巨大的单烯烃分子的时候,想到了一个问题。
2.2 题目描述
给你一棵树,一些边有标记,对于每条有标记的边,在树中找到包含这条边的一条最长链,并输出长度。
Input
第一行一个整数 id 表示测试点的编号。
多组数据,第二行一个整数 T 表示数据组数。
对于每组数据,第一行两个整数 n,m 表示节点的个数,和被标记的边的个数。
我们规定 1 是根,第二行 n − 1 个整数给出 2 ∼ n 父亲的编号,保证f(ai) < i。
第三行 m 个整数范围在 [2,n] 表示哪个点的父边被标记过。
多组数据,第二行一个整数 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