10.15T3 树形DP
Description
对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大。例如下图左边的树(图1)抽出一部分就变成了右边的一个毛毛虫了(图2)。
Input
第一行两个整数N,M,分别表示树中结点个数和树的边数。
接下来M行,每行两个整数a, b表示点a和点 b有边连接(a, b≤N)。你可以假定没有一对相同的(a, b)会出现一次以上。
接下来M行,每行两个整数a, b表示点a和点 b有边连接(a, b≤N)。你可以假定没有一对相同的(a, b)会出现一次以上。
Output
写入一个整数, 表示最大的毛毛虫的大小。
Sample Input
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
Sample Output
11
Hint
【数据范围】
40%的数据, N≤50000
100%的数据,N≤300000
40%的数据, N≤50000
100%的数据,N≤300000
实际上就是从下到上面扫一遍就可以了,根节点的情况特殊处理一下就好了
code:
1 #include<iostream> 2 #include<cstdio> 3 #define N 1000006 4 using namespace std; 5 struct node{ 6 int u,v,w; 7 }e[N]; 8 int first[N],nxt[N],cnt; 9 int siz[N],fa[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 int ans,son[N]; 17 void dfs(int x){ 18 siz[x]=son[x]; 19 int now(0); 20 int max0=0,cimax0=0; 21 for(int i=first[x];i;i=nxt[i]){ 22 int v=e[i].v; 23 if(v==fa[x])continue; 24 fa[v]=x; 25 // cout<<v<<" "<<x<<'\n'; 26 dfs(v); 27 ans=max(ans,max0+siz[v]-1+son[x]); 28 max0=max(max0,siz[v]); 29 siz[x]=max0+son[x]-1; 30 } 31 // cout<<"now->"<<x<<" siz->"<<siz[x]<<'\n'; 32 } 33 int main(){ 34 int n; 35 cin>>n; 36 cin>>n; 37 for(int i=1;i<=n;i++){ 38 int u,v; 39 cin>>u>>v; 40 add(u,v); 41 add(v,u); 42 son[v]++; 43 son[u]++; 44 } 45 fa[1]=1; 46 dfs(1); 47 cout<<ans; 48 return 0; 49 }
over