[NOIP2013] 운송
기술
국영
n 개 에서 번호 도시, 1 n은 도시 사이에있다 m 양방향 도로. 모든 도로는 무게 제한이라 차량의 무게 제한이 있습니다. 있습니다 상품의 교통 Q 트럭 여러 상품을 수송하기까지 차량의 중량 제한을 초과하지 않고, 드라이버, 모든 차를 알고 싶어요.
입력
정수의 스페이스로 구분하여 처음 두 행
N , m은 A가 소유 나타내고 n 개의 도시 및 m의 도로.
다음 m의 라인마다 3정수의 X , Y , Z 공간에 의해 분리 된 두 개의 정수 사이의 각각은, 상기 대표 하는 도시에서 x를 도시 Y의 수에 대한 제한이 중량 Z 도로. 참고 :X는 동일하지 않는 예를 도시 두 도로 사이의 수가 될 수있다.
정수가 다음 줄 q는 표현 Q의 트럭이화물이 필요합니다.
다음 Q의 두 정수의 라인 X , Y 공백으로 구분 사이가에서 트럭이 필요 나타내는 X 로 도시 교통화물 Y 도시,주의 :X는 동일하지 않는 Y한다.
다음 m의 라인마다 3정수의 X , Y , Z 공간에 의해 분리 된 두 개의 정수 사이의 각각은, 상기 대표 하는 도시에서 x를 도시 Y의 수에 대한 제한이 중량 Z 도로. 참고 :X는 동일하지 않는 예를 도시 두 도로 사이의 수가 될 수있다.
정수가 다음 줄 q는 표현 Q의 트럭이화물이 필요합니다.
다음 Q의 두 정수의 라인 X , Y 공백으로 구분 사이가에서 트럭이 필요 나타내는 X 로 도시 교통화물 Y 도시,주의 :X는 동일하지 않는 Y한다.
산출
총 출력
Q의 라인, 각 트럭 나타내는 각 정수는 최대 부하입니다. 트럭이 대상, 출력에 도달 할 수없는 경우 - 1 .
샘플 입력
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
샘플 출력
(3)
-1
3
힌트
의 경우 30 %데이터 . 1 ≤ N- ≤ 1,000 , . 1 ≤ m ≤ 10000 , . 1 ≤ Q ≤ 1,000
대데이터 60 % . 1 ≤ N- ≤ 1,000 , . 1 ≤ m ≤ 50000 , . 1 ≤ Q ≤ 1,000
대데이터 100 % . 1 ≤ N- ≤ 10000 , . 1 ≤ m ≤ 50000 , . 1 ≤ Q ≤ 30000 , 0 ≤ Z ≤ 100000
문제 해결 아이디어
도면 중 적어도 한쪽의 경로에, 두 지점 사이의 최대 스패닝 트리가없는 경우에 각각의 에지 값은 그 가장자리와 동일한 값보다 큰 것을 특징으로하는 우선,이 도면에서, 특정 경로가있다.
당신이 그 (것)들에게 최대 스패닝 트리를 요청하고 경우에 따라서 다음 최소 유지하기 위해 LCA를 사용합니다.
시간 복잡도 : O (nlogn)
사용법 #include <iostream> #INCLUDE <cstdio> #INCLUDE <알고리즘> 네임 스페이스를 사용하여 표준; 구조체 데이터 { INT의 X, Y, V; t} [50001], D [20001]; INT n을, m은 [10001] [21], FA [10001], H [10001], CNT, FX, FY, ANS, P [10001] ID [10001], X F를 [10001] [21]이야 ,와이; 부울 CMP (데이터 A, 데이터 B)는 { AV> BV 리턴; } INT 아버지 (INT a) { 경우 FA ([A] = A!) FA [A] = 아버지 (FA [A]); FA를 반환 [A]; } 공극 부가 (a, INT의 B, C의 INT를 INT) { CNT ++; D [CNT] .x를 = B; D [CNT] .Y = H의 [A]; D [CNT] .V = C; H [A] = CNT; } 공극 DFS는 INT (a) { 위해 (; 나는 <= 20, I = 1 int로 난 ++) { F [A] [I] = F [F [A] [I-1] [I-1]; S [A] [I] = 분 (S [A] [I-1], S [F [A] [I-1] [I-1]); } 에 대해 (나는; I = h를 [A] 값 int I = D [I]를 .Y) { 경우 (! 피 [D [I] .x를]) { P [D [I]를 .x를] = P를 [A ] +1; F [D [I] .x를] [0] =; S [D는 [I] .x를] [0]를 D = [I] .V; ID [D의 [I] .x를] = ID [A]; DFS (d [I] .x를); } } } 공극의 LCA (INT의 B를를 INT) { 경우 (p [A]> P [B]) { 위해 (20 = 1을 나타내는 int I> = 0; I -) { [A F 경우 (p [ [I]]> = P [B]) { ANS = 분 (ANS, S [A] [I]); A = F [A] [I]; } } } 경우 (p는 [A]를 <p는 [B]) { 위해은 (INT I = 20, I> = 0; I -) { 경우 (p> = P [A] [B] [i]는 F]) { 대해 INT (I = 1; i가 <= N; 내가 ++) FA [I] = 1; ANS = 분 (ANS, S [B] [I]); B = F [B] [I]; } } } (I = 20에서 INT; I> = 0; I -)에 대해 { 경우 (! F [A] [I] = F [B] [I]) { ANS = 분 (ANS, S [A] [나는]); ANS = 분 (ANS, S [B] [I]); A = F [A] [I]; B = F [B] [I]; } } 경우 (A = B!) { ANS = 분 (ANS, 님의 [A] [0]); ANS = 분 (ANS, S [B] [0]); } } INT의 main () { 는 scanf ( "% d 개 %의 D", 및 N, m); scanf와 ( "% D % D % D", t [I] .x를, t [i]는 .Y, t의 [I] .V) 미국 (; I <= m 내가 ++ I = 1 INT)을; 대해 INT (I = 1; I <= m; 정렬 (t + 1, t +에서의 m + 1, CMP); 기 = 아버지 (t의 [I] .Y); 경우 (FX 기 =!) { FA [FX] = 기; 추가 (t [I] .x를, t [i]는 .Y, t [I] .V); 추가 (t의 [를 I] .Y, t [I] .x를, t [I] .V); } } 에 대해 (; 나는 = <N; I = 1 int로 난 ++) { 경우 {(ID [I]!) P [I] = 1; ID [I] = 1; DFS (I); } } 는 scanf ( "%의 D", m); 대해 INT (I = 1; I <= m; 내가 ++) {를 ANS = 10000000; scanf와 ( "% d 개 %의 D ', X, Y); 만약 (ID [X] == ID [Y]) { LCA (X, Y); 의 printf ( "% D \ 없음", ANS); } printf와 다른 ( "- 1 n \");