문제 나무 애벌레 루오 구 P3174에 [DP] && 용액

주제 포털

주제 설명 :

나무를 들어, 우리는 가닥과 출력 단자에 연결된 가닥 측면 애벌레, 더 많은 포인트, 큰 애벌레와 같은 모습으로 올 수 있습니다. 우측의 부분을 추출하는 트리 왼쪽 그림 (도. 1)는 무한 궤도로되는 바와 같이 (도. 2).

여기에 그림 삽입 설명
입력 형식
첫 번째 행의 두 정수 N, M, 각각, 에지의 수와 트리의 노드 수, 트리.
다음에 M 행, 각 행에 두개의 정수 A, B 나타내는 점 a와 b (a, b≤N) 가장자리를 연결했다. 당신은 동일한 한 쌍의 개 (A, B) 두 번 이상 나타납니다 있다고 가정 할 수 없다.

출력 형식을
가장 큰 유충의 크기를 나타내는 정수입니다.


분석 :

질문 너를 체인이 체인에 포함 된 노드의 최대 수 있도록 변환 할 수 있습니다.
노드 X의 경우, 우리 설정 [ 엑스 ] 그것은이다 엑스 인가 뿌리 축제의 포인트 가장 축제의 포인트 설정 DP [X]는 x의 루트 노드의 최대 수입니다

우리는 자식 노드의 x 및 y를 열거하여 업데이트 된
다른 자식 노드도 포함하면서 직접 그와 연결되어 있기 때문에, 모든 X의 경우, y는 많아야 하나를 선택, 찾기 어렵습니다.
설정 [ 엑스 ] 테이블 표시 엑스 조차 포인트 NUM 제공자는 [X] 접속 번호 X 점을 나타내고

그리고 우리는 다음과 같은 식을 얻을 수 있습니다 :
[ x ] = m a x ( d p [ y ] + n u m [ x ] 1 )   ( y s o n ( x ) ) DP [X] = 최대 (DP [Y] + NUM [X] -1) \ (아들의 Y \ (X))

그래서 수요 방정식 DP 글쎄, 답을 찾는 방법을 고려한다.

찾기 어렵지 않다, 사실, 최종 답변 1 함께 노드가 가장 긴 사슬 체인의 길이와 횟수 -1 .

우리는 경우에만 DP에 대한 답을 업데이트해야합니다.


암호

#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;
}

추천

출처blog.csdn.net/huang_ke_hai/article/details/89003707