xsy 2,018] NOIP2013 운송

[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한다.

산출

총 출력 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 \");

 

  

 

추천

출처www.cnblogs.com/ez-syh/p/11615450.html