이상 2019 소 오프 여름 학교 캠프 (제 4 호) J-무료

> 포털 <

질문의 의미 : 당신이 제공하는 N 도시, m의 각각의 비용이 길을 소요 한 후 도로, 이제 줄 케이 , 기회를 최대한 활용할 수 k 개의 도로의 비용이 0, 시작 지점에서 질문 끝에 t가 지출을 최소 비용

아이디어 : 가장 고전 알몸 단락 문제의 계층보기

방법 1

암호

#INCLUDE <비트 / STDC ++ H.>
 은 USING  공간 STD;
 구조체 에지 { INT 에, 선정]} 
의 typedef 쌍 < INT , INT > P; // 먼저 인 최단 거리, 제 정점 번호 

CONST의  INT max_v = 2,000,005 ;
 INT N-, m은, S, T, K는,
 INT D [max_v] 
벡터 <엣지> G는 [max_v] 

무효화 익스트라을 () 
{ 
    priority_queue <P 벡터 <P> 그레이터 <P >> ; 케 
    memset 함수 (D , 0x3F입니다 , sizeof의 (D)), 
    D [S] =0 ; 
    que.push (P ( 0 , S)); 
    
    반면 (! {que.empty ()) 
        P를 P = que.top (); que.pop ();
        INT의 V = p.second;
        경우 (d [V] <p.first) 계속 ;
        위한 ( int로 I = 0 () 나 G를 <[V]를 크기는, 난 ++ ) { 
            에지 E = G [V] [I];
            경우 (D [e.to]> D [V] + e.cost) { 
                D [e.to] = D [V] + e.cost; 
                que.push (P (d [e.to, e.to)); 
            } 
        }
    } 
} 

INT 의 main () 
{ 
    는 scanf ( " % D % D % D % D % D " , 및 N, M, S, T, K);
    위한 ( int로 I = 1 ; I <= m; 내가 ++ ) {
         int로 U, V, 비용; 
        scanf와 ( " % D % D % D ' , U, V, 및 비용);
         ( INT의 J = 0 ; J <= K, J ++ ) { 
            G [U + N * J] .push_back ({V + N * J 비용}); 
            G [V + N *의 J] .push_back ({U + N * J 비용});
            만약 (j < k)는 { 
                G [U + N 개 *의 J] .push_back ({V + N * (j + 1 ), 0 }); 
                G [V + N *의 J] .push_back ({유 + N * (j + 1 ), 0 }); 
            } 
        } 
    } 
    익스트라 (); 
    // INT ANS = 0x3f3f3f3f;
    // 대해 INT (I = 0; I는 <= K를, 난 ++) ANS = 분 (ANS, DIS [t + N * I]); 
    의 printf ( " % D \ 없음 " , D [t + K *의 N]);
    반환  0 ; 
}
코드보기

 

두 번째 방법

그래서 어떤 사람들은 다 익스트라의 알고리즘의 스택을 통과하지 않은이 질문에 직접 폭력을 최적화하는 것이 가장 당황 스럽네요? ? ? 그런 다음 모양 n은 m 괜찮아, 또한, 중요하지 1E3, 최대 1E6 복잡성보다 작습니다. 물론, 그것은 또한 최적화 된 알고리즘 또는 SPFA, 내일 또 다른 모습을 사용합니다

암호

#INCLUDE <비트 / stdc ++ H.>
 사용  스페이스 성병; 
쌍 타입 정의 < INT , INT > P; 

CONST의  INT의 MAX_N = 1,005 ;
INT의 N, M, S, T, K; 
벡터 <P> G [MAX_N];
INT D [MAX_N] MAX_N]; 

보이드 익스트라 () 
{ 
    memset 함수 (d, 0x3F입니다 , 는 sizeof (d)); 
    D [S] [ 0 ] = 0 ;  <P> 케; 
    que.push ({S, 0 }); 
    
    동안 (!que.empty ()) {
         INT U = que.front () 제, t =. que.front () 제.; que.pop ();
        위한 ( int로 I = 0 ; I <는 G를 [U] 크기는 (); 나는 ++ ) {
             INT의 V = G [U] [i]는 좁은 방 비용 = G [U] [I] .second;
            경우 (d는 [V] [t]가> D [유] [t]가 + 선정) d는 [V] [t]가 D가 = [U] [t] + 비용 que.push ({V, t});
            만약 (t <K && D [V] [t + 1 ]> D [U] [t]) d는 [V] [t는 + 1 ] D가 = [U] [t] que.push ({V, t + 1 }); 
        } 
    } 
} 

int로 주 () 
{ 
    는 scanf를 ( " % D % D % D % D % D ", 및 N, M, S, T, K);
    위한 ( int로 I = 0 ; I <m은, 내가 ++ ) {
         int로 U, V, 비용; 
        scanf와 ( " % D % D % D ' , U, V, 및 비용); 
        G [U] .push_back ({V 비용}); 
        G [V] .push_back ({U 비용}); 
    } 
    익스트라 (); 
    의 printf ( " % D \ 없음 " , D [t] [K]);
    반환  0 ; 
}
코드보기

 

추천

출처www.cnblogs.com/wizarderror/p/11261270.html