질문의 의미 : 당신이 제공하는 N 도시, m의 각각의 비용이 길을 소요 한 후 도로, 이제 줄 케이 , 기회를 최대한 활용할 수 k 개의 도로의 비용이 0, 시작 지점에서 질문 의 끝에 t가 지출을 최소 비용
아이디어 : 가장 고전 알몸 단락 문제의 계층보기
방법 1
암호
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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, 내일 또 다른 모습을 사용합니다
암호
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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 ; }