P3177 [HAOI2015] 염색 트리 (트리 DP)

 

주제 링크 : https://www.luogu.org/problem/P3177

제목 설명

N 나무의 점은 여러 가지가있다 나무는 측면 에지 가중치를 가지고있다. N 개의의 K 0에서 당신에게 양의 정수를 제공하기 위해, 당신은 검은 색으로 염색 및 기타 NK가 흰 반점 착색 된 트리에서 K 포인트를 선택해야합니다. 모든 점 염색 후에는 함께 매 2 검은 점과 흰 점 이십 이익 사이의 거리 사이의 거리를 얻을 것이다. Q. 최대 장점은 무엇입니까.

입력 형식

첫 번째 라인은 두 정수 N, K. 포함 이어서 N-1 세 줄 각각 양의 정수의 FR, DIS에, 트리에 DIS (FR, 행)의 에지 길이의 존재를 나타낸다. 입력은 모든 점 유니콤 사이에 확인합니다.

출력 형식

출력 최대 이익을 나타내는 양의 정수입니다.

샘플 입출력

입력 # 1
3 1 
1 2 1 
1 3 2
출력 # 1

설명 / 팁

데이터의 100 %, 0 <= K <= N <= 2,000

 

 

문제 해결 방안은 첫째, 우리는 응답 측으로 전류 기여 w = 측면 길이 측의 기여도를 계산할 수 i가 최대 값 J 흑점 그린 [I] [j]가 서브 트리에있는 상태 DP 설정 * 번호 * 블랙 도트의 수가 다른 측면에 백색 도트 수의 측부 *의 흰색 점의 양측의 검은 점 + 측면 길이 * 번호의 타측 단부는, 그 상태 천이를 행할 수있다. 그것은 전송이 코팅 불법 상황의 시점을 결정할 필요가 있음을 주목할 필요가있다, 예를 들어, 우리는 자식 노드의 현재 하위 트리에 열거, 우리는 우리가 다른에 아이를해야합니다, 그것은 검은 점을 포함 열거 나무는 J의 전체 선택 - 검은 반점을 상태를하지만, 다른 하위 트리의 전체 크기가 J보다 작은 경우 - 다음 (1), 다음 상태는 분명히 합법적없는, 그래서 우리는 케이스를 제거해야합니다. (필자는 WA가 ..QAQ 울고 생각하지 않았다)

 

#INCLUDE <비트 / stdc ++ H.> 
네임 스페이스를 사용하여 표준; 
CONST의 INT maxn = 2e3 + (10); 
타입 정의 오래 오래 LL; 
LL DP [maxn] maxn]; 
N INT, K; 
구조체 일 { 
	옆에있는 INT; 
	발 LL; 
STM} [maxn * 2; 
INT의 CNT; 
INT 헤드 [maxn]; 
INT 합 [maxn]; 
부가 공극 (INT U, V의 INT, LL의 발) { 
	STM [CNT] .TO = V; 
	STM [CNT] 다음 내용 = 헤드 [U]; 
	STM [CNT] .val = 브로; 
	헤드 [U] = CNT ++; 
} 
공극 DFS (INT 이제 INT FA) { 
	합 [현재] = 1; 
	위한 (INT 헤드 I = [현재] ~ I, I = STM [i]는 다음 내용) { 
		= INT STM에 [I] .TO; 
		경우 (FA를 ==하기 위해) 계속; 
		DFS (지금까지); 
		[발] 이제] + = 합을 합산; 
	} 
}
보이드 dfs1은 (현재 INT, INT FA) { 
	DP이 [현재] [0] [현재] DP가 = [1] = 0; //这两个状态肯定合法
	대 (INT I = 헤드 [현재] ~ I, I STM = [I] 다음 내용) { 
		= INT STM에 [I] .TO; 
		LL 브로 STM = [I] .val; 
		(FA를 ==하기가) {경우 
			계속; 
		} 
		dfs1 (행 지금); 
		(INT J = 분 ([현재] 합계 K) J> = 0; J -) 대 { 
			대 (INT의 m = 0; 행] m <= J && m <= 합; m ++) {	 
			경우 (DP [ 이제] [JM] == - 1) 계속 //判断当前状态转移是否合法
			DP [현재] [J] = 최대 (DP [현재] [J], DP [현재] [JM] + DP [발] [m] +의 Val * m *의 (km) + (-m [을] 합) 브로 * (NK 합 [을] + m)); 
			} 
		} 
	} 
} 
INT의 main () { 
	U를 INT, V; 
	발 LL; 
	CNT = 0; 
	memset 함수 (헤드, -1는 sizeof (헤드)); 
	난 <N; 위해 (ⅰ = 1 int로;
	memset 함수 (DP, -1는 sizeof (DP));
	scanf와 ( "%의 D % d에", N, K); 
		scanf와 ( "% D % % LLD D ', U, V, 및 발); 
		추가 (U, V, 발); 
		추가 (V, U, 발); 
	} 
	DFS (1, -1); 
	dfs1 (1, -1); 
	의 printf ( "% LLD \ 없음"DP [1] [K]); 
	0을 반환; 
}

  

 

추천

출처www.cnblogs.com/Zhi-71/p/11748265.html