[HAOI2009] 毛毛虫

试题描述

对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大。例如下图左边的树(图 1 )抽出一部分就变成了右边的一个毛毛虫了(图 2 )。

输入数据

在文本文件 worma.in 中第一行两个整数 N , M ,分别表示树中结点个数和树的边数。

接下来 M 行,每行两个整数 a, b 表示点 a 和点 b 有边连接( a, b ≤ N )。你可以假定没有一对相同的 (a, b) 会出现一次以上。

输出数据

在文本文件 worma.out 中写入一个整数 , 表示最大的毛毛虫的大小。

样例输入

13 12
1 2
1 5
1 6
3 2
4 2
5 7
5 8
7 9
7 10
7 11
8 12
8 13

样例输出

11

测试数据范围

40% 的数据, N ≤ 50000

100% 的数据, N ≤ 300000

 

题解:

简单的树形DP啊,只是感觉要枚每一个点作根,想想发现是不用的

有两种情况

1.路径不过起始点的,显然会被统计到,因为会枚举到除fa的所有子节点

2.过起始点,说明是沿着fa的一直上去的一条路径,那么在起始点显然是会被统计到的

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 const int N=300005,INF=-2e9;
 8 int gi(){
 9     int str=0;char ch=getchar();
10     while(ch>'9' || ch<'0')ch=getchar();
11     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
12     return str;
13 }
14 int n,f[N],head[N],m,num=0,val[N];
15 struct Lin{
16     int next,to;
17 }a[N<<1];
18 void init(int x,int y){
19     a[++num].next=head[x];
20     a[num].to=y;
21     head[x]=num;
22 }
23 int ans=0;
24 void dfs(int x,int last){
25     int u,mx=INF;
26     f[x]=val[x];
27     for(int i=head[x];i;i=a[i].next){
28         u=a[i].to;
29         if(u==last)continue;
30         dfs(u,x);
31         ans=max(ans,mx+f[u]+val[x]-1);
32         if(f[u]>mx)mx=f[u];
33         f[x]=max(f[x],f[u]+val[x]-1);
34     }
35 }
36 int main()
37 {
38     freopen("worma.in","r",stdin);
39     freopen("worma.out","w",stdout);
40     n=gi();m=gi();
41     int x,y;
42     for(int i=1;i<=m;i++){
43         x=gi();y=gi();
44         init(x,y);init(y,x);
45         val[x]++;val[y]++;
46     }
47     dfs(1,1);
48     printf("%d\n",ans);
49     return 0;
50 }

 

posted @ 2017-07-16 20:01  PIPIBoss  阅读(164)  评论(0编辑  收藏  举报