加工树枝
Dragon同学一天捡到了一根非常非常巨大的树枝,于是同学就想啊,如果把这根树枝多余的分叉剔掉最后剩下一根没有分叉的木棍,用它自卫就没人敢欺负我们科学家了呀:)
你的任务是,对给定树枝,求出它包含的最长木棍。
输入文件:
第一行一个正整数n,表示顶点数,顶点从1至n编号(N <= 100000)。
然后n – 1行每行两个正整数u, v表示u, v之间有一条边,每条边的长度为1。
保证输入的是一棵树。
输出文件:
只有一行,表示给定树的最长链长度。
Tree.in 5 1 2 1 3 1 4 1 5 |
Tree.out 2
|
f[][1]表示是与当前节点连接的儿子链的最长的长度。
f[][0]表示当前节点连接起来的最大的值。
#include<cstdio> #define max 200010 int f[100010][2],n[max],x[max],k[max]; int m,o; bool v[max]; void dp(int a) { int t; v[a]=1; f[a][0]=0; f[a][1]=0; t=k[a]; while (t) { if (!v[x[t]]) { dp(x[t]); if (f[x[t]][1]+f[a][1]>f[a][0]) f[a][0]=f[a][1]+f[x[t]][1]+1; if (f[x[t]][0]>f[a][0]) f[a][0]=f[x[t]][0]; if (f[x[t]][1]>=f[a][1]) f[a][1]=f[x[t]][1]+1; } t=n[t]; } if (f[a][1]>f[a][0]) { //*(*(f+a)+1)=*(*(f+a)); f[a][0]=f[a][1]; } } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d",&m); int a,b; for (int i=1;i<=m;i++) { scanf("%d %d",&a,&b); x[++o]=b; n[o]=k[a]; k[a]=o; x[++o]=a; n[o]=k[b]; k[b]=o; } dp(1); printf("%d\n",f[1][0]); return 0; }