소 오프 더 학교 네 번째 J 무료 짧은

질문의 의미 :

최단 경로를 찾는,하지만 당신은 에지 경로의 길이가 0이 시간을 케이 수있는 기회를 가질 수있다.

해결 방법 :

익스트라 실행 K + 1 번, K + 1 기의 배열과 DIS 우선 순위 큐를 상상해는 K 에지의 k 번째 그룹 이완 동작을 제거하는 수단을 매 2 나, 이완, J, 및 거리 L (i, j)로하면, 단지 본 업데이트 DIS 어레이 그룹 DIS [J] = 그래서 DIS [I] + L [I, J, 다음 그룹의 상기 갱신하므로 dis` [J] = DIS [I] 에지 삭제 등가 (I, J)

사용법 #include <iostream> 
#INCLUDE <큐> 
#INCLUDE <벡터> 
#INCLUDE <CString을>
 #DEFINE INF 0x3f3f3f3f
 구조체 포인트 {
     INT의 N, DIS; 
    친구 부울  연산자 > ( CONST 포인트 & A CONST 요점 b) {
          > a.dis b.dis; 
    } 
    친구 부울  연산자 <( CONST 포인트 & A CONST 포인트 및 B)는 {
         반환 a.dis를 < b.dis; 
    }  
    포인트 () {}
    포인트 ( INTA, INT의 B) { 
        N- = A; DIS = B; 
    } 
} 
은 USING  공간 STD,
 INT는 하기 Lik [ 1003 ] [ 1003 ]
 int로 [DIS 1003 ] [ 1003 ]을; // j 번째 후에 삭제 나 모서리 최단 거리를 가리키는 
priority_queue를 <포인트 벡터 <점> 그레이터 <점 >> 케 [ 1,003 ] 
벡터 <포인트> 링크 [ 1003 ];
 INT 의 main () {
     INT N-, m, S, T, K, 
    는 scanf ( " % %% D D D D D % % " , 및 N-, m, S, T & & K)
     
    memset 함수 (DIS, INF, 는 sizeof DIS); 
    memset 함수 (이겨, INF, 는 sizeof 이겨);
    위한 ( int로 난 = 1 ; i가 <m = 내가 ++ ) {
         int로 A, B, C를; 
        scanf와 ( " % D % D % D ' , A, 및 B, 및 C);
        경우 (a ==의 b) 계속 ;
        { 
            사장님은 [A]는 [B] = 분 (사장님 [A] [B], c); 
            이겨 [B] [A] = 분 (사장님 [B] [A], c); 
        } 
    } 
     
//   대해 (; 나는 = <N; I = 1 int로 난 ++) {
 //       대 (INT J = 1; J <= N; J ++) {
 //           의 printf ( "%의 D"사장님 [I] [J]);
//       }
 // 용       의 printf ( "\ n")를;
//   } 
     
    에 대해 ( int로 I = 1 ; i가 N <; 내가 ++ ) {
          ( INT의 J = 나 + 1 , J <= N; J ++ ) {
             경우 (이겨 [I] [J] < INF) { 
                링크 [I] .push_back (포인트 (j, 이겨 [I] [J])); 
                링크 [J] .push_back (포인트 (I, 이겨 [J] [I])); 
            } 
             
        } 
    } 
     
//   ( "%의 D '링크 [I] 크기는 ())의 printf을위한은 (i ++; i가 N = <I = 1 INT); 
     
//   시스템 ( "일시 중지"); 
    케 [ 0] .push (포인트 (S, 0 )); 
    DIS [ 0 ] [S] = 0 ; 
     
    위한 ( int로 I = 0 ; I는 <= K를, 난 ++ ) {
         동안 (! 케 [I] .empty ()) { 
             
            포인트 TMP = 케 [I] .top (); 
            케 [I] .pop (); 
            INT U = tmp.n;
            INT nowd = tmp.dis;
            경우 (nowd> DIS [I] [U]) 계속 ; 
             
//           의 printf ( "* D % % D \ n", U, nowd); 
             
             ( INT의 J = 0 ; J <링크 [U] 크기는 (); J ++ ) {
                INT의 V = 링크 [U] [J] .N;
                INT의 D = 링크 [U]는 [J]를 .dis; 
                 
                경우 (DIS [i]는 [V]> nowd + d) { 
                    DIS [I] [V] = nowd + D; 
                    케 [I] .push (점 (V, DIS [i]는 [V])); 
                } 
                 
                경우 (I <K && DIS [I + 1 [V]> nowd) { 
                    DIS [I + 1 [V] = nowd; 
                    케 [내가 + 1 ] .push (점 (V, DIS [I + 1 [V])); 
                } 
                 
//               대 (INT 0 = w <= K w, w ++) {
 //                  대 (INT의 R = 1, R <= N, R ++) {
 //                       의 printf ( "%의 D"DIS [w] [R]);
//                   }
 // 용                   의 printf ( "\ n")를;
//               }
 // 용               의 printf ( "\ n")를; 
                 
            } 
             
        } 
    } 
//   대 (INT w = 0 <= K w; ++ w) {
 //       대 (INT, R 1, R <= N, R ++) {
 //           의 printf ( "%의 D"DIS [w] [아르 자형]);
//       }
 // 용       의 printf ( "\ n")를;
//   } 
    INT 미네소타 = INF;
    위한 ( int로 = 1을 0 ; 나는 <= K를;) { = 분 (a, DIS [S] [t]); 
    } 
    의 printf ( " % D \ 없음 " , a); 
}

 

추천

출처www.cnblogs.com/isakovsky/p/11257352.html