[Dp] && solution to a problem tree caterpillar Luo Gu P3174

Topic Portal

Subject description:

For a tree, we can be a strand and the strand sides connected to the out come into looks like a caterpillar, the more points, the greater the caterpillar. Such as trees left figure (Fig. 1) extracting a portion of the right side becomes a caterpillar (FIG. 2).

Here Insert Picture Description
Input format
of the first row two integers N, M, respectively, the number of edges and the number of nodes in the tree, the tree.
Next M rows, each row two integers a, b represent points a and b have connecting edges (a, b≤N). You can not assume that a pair of identical (a, b) appears more than once.

Output formats
An integer representing the size of the largest caterpillars.


analysis:

Questions can be converted to make thee a chain, the maximum number of nodes contained in this chain.
For a node x, we Assume d p [ x ] Yes With x for root Festival point of most Big Festival point number Set dp [x] is the root of x is the maximum number of nodes

We updated by enumerating the child node x y
difficult to find, for every x, y at most only choose one, while the other child nodes also be included, because directly connected with him.
Assume n in m [ x ] table Show x The phase even of point of More number Provided NUM [x] denotes the point x the number connected

Then we can get the following equation:
d p [ x ] = m a x ( d p [ y ] + n u m [ x ] 1 )   ( y s o n ( x ) ) dp[x]=max(dp[y]+num[x]-1)\ (y\in son(x))

So the demand equation dp Well, consider how to find the answer.

Not difficult to find, in fact, the final answer 1 The number of times with the longest chain length of the chain and, together with the nodes -1

We only need to update the answer to when dp.


Code

#include<bits/stdc++.h>
using namespace std;
struct node{
    int y,Next;
}e[700000];
int linkk[700000];
int sum[700000];
int num[700000];
int dp[700000];
int n,m,len=0;
//int maxx1;
//int maxx2;
int maxxx=0;
void insert(int x,int y){
    e[++len].Next=linkk[x];
    e[len].y=y;
    linkk[x]=len;
}
void find_sum(int x,int fa){
    sum[x]=1;
    for (int i=linkk[x];i;i=e[i].Next){
	    int y=e[i].y;
	    if (y==fa) continue;
	    find_sum(y,x);
	    sum[x]+=sum[y];
	}
}
void treedp(int x,int fa){
	int maxx1=0,maxx2=0;
	dp[x]=1;
    for (int i=linkk[x];i;i=e[i].Next){
	    int y=e[i].y;
	    if (y==fa) continue;
	    treedp(y,x);
	    if (dp[y]>maxx1)
	      maxx2=maxx1,maxx1=dp[y];
	    else maxx2=max(maxx2,dp[y]);//更新最长链和次长链
	    dp[x]=max(dp[x],dp[y]+num[x]-1);//更新
	}
	maxxx=max(maxxx,maxx1+maxx2+num[x]-1);//更新
}
int main(){
	freopen("WORM.in","r",stdin);
	freopen("WORM.out","w",stdout);
	scanf("%d %d",&n,&m);
	for (int i=1,x,y;i<=m;i++)
	  scanf("%d %d",&x,&y),insert(x,y),insert(y,x),num[x]++,num[y]++;//记录相连的点的个数
	for (int i=1;i<=n;i++) dp[i]=1;
	find_sum(1,0);//突然发现没什么用。。、。
	treedp(1,0);
	printf("%d",maxxx);
	return 0;
}

Guess you like

Origin blog.csdn.net/huang_ke_hai/article/details/89003707