私があなたを正しく理解していないとしたら、出発都市と目的都市があり、出発都市から目的地の都市に到達するには、最小限のフライトで道を見つける必要があります。それは大丈夫ですか?
動的計画法で解決策をどのように見るか、フライトのみを使用dp[i][j]
して数字で都市に到達できる最適な時間を保存します。最初は、 のすべての要素が に設定されています。各ステップでそれを更新しようとします。したがって、アルゴリズムは次のようになります。i
j
dp
infinity
dp[0][0] = 0;
priority_queue< pair<int,int> > q;
q.Add( make_pair(0,0) );
/*in q we store pair, where first is time of arrival in city,
and the second is THAT city.*/
while there are element is queue {
x = the first one element ( where time is the smallest )
remove first element from queue
if x.city == destination city
break cycle;
then
for all j
if dp[x.city][j] < x.time + 50
for all flights(from, to) where from==x.city we try to update
if( dp[to][j+1] < dp[x.city][j] + 50 + jurney_duration ) {
dp[to][j+1] = dp[x.city][j] + 50 + jurney_duration ;
q.add( make_pair(dp[x.city][j] + 50 + jurney_duration, to) );
}
}
x
したがって、答えを見つけるには、最小のwhereを見つけるだけでよくdp[final_dest][x] != infinity
、これx
が答えになります。
O(n*n*m)
の本体は( where ) 回while-cycle
だけ実行され、cycle には と の 2 つのサイクルがあるため、効率は になります。最初に n 回だけ実行します。これは、パスがフライトより少ない回数しか使用しないためです。前にいた都市に戻る必要はありません。n
n - number of cities
n
m
for-cycle
N
編集:
実際には、Adjacency listのようなフライトの情報を保存すると、効率がさらに向上します: O(n*m)。たとえば、番号のある都市がm ii
に隣接している場合、N*m 0が得られるためです。 + N*m 1 + ... + N*m N = N*(m 0 + m 1 + ... + m n ) = N*M、m i th == Mの合計(M はフライトの総数)。
プライオリティ キューの詳細