最小堆优化
优化的点是每次直接通过最小堆的堆顶找到最短路径最小的未搜索的点 省去了一层遍历
const int N = 1e6 + 10 , INF = 0x3f3f3f3f ;
int h[ N] , e[ N] , ne[ N] , w[ N] , n, m, idx = 0 , d[ N] ;
bool visited[ N] ;
void add ( int a, int b, int c) { e[ idx] = b; ne[ idx] = h[ a] ; w[ idx] = c; h[ a] = idx++ ; }
int dijkstra ( int s)
{ priority_queue< pair< int , int > , vector< pair< int , int >> , greater< pair< int , int >> > m_heap; fill ( d, d + N, INF) ; d[ s] = 0 ; m_heap. push ( { 0 , 1 } ) ; while ( m_heap. size ( ) ) { int u = m_heap. top ( ) . second, ud = m_heap. top ( ) . first; m_heap. pop ( ) ; if ( visited[ u] ) continue ; visited[ u] = true ; for ( int v = h[ u] ; v != - 1 ; v = ne[ v] ) { int j = e[ v] ; if ( visited[ j] == false && ud + w[ v] < d[ j] ) { d[ j] = ud + w[ v] ; m_heap. push ( { d[ j] , j} ) ; } } } return d[ n] == INF ? - 1 : d[ n] ;
}
邻接矩阵版
const int N = 510 , INF = 0x3f3f3f3f ;
int G[ N] [ N] , d[ N] , n, m, a, b, c;
bool visited[ N] ;
int Dijkstra ( int s)
{ memset ( d, 0x3f , sizeof d) ; d[ s] = 0 ; for ( int i = 1 ; i <= n; ++ i) { int u = - 1 ; for ( int j = 1 ; j <= n; ++ j) if ( visited[ j] == false && ( u == - 1 || d[ j] < d[ u] ) ) u = j; visited[ u] = true ; for ( int v = 1 ; v <= n; ++ v) if ( visited[ v] == false && G[ u] [ v] != INF && G[ u] [ v] + d[ u] < d[ v] ) d[ v] = d[ u] + G[ u] [ v] ; } return d[ n] == INF ? - 1 : d[ n] ;
}
int main ( )
{ cin >> n >> m; fill ( G[ 0 ] , G[ 0 ] + N * N, INF) ; while ( m-- ) { cin >> a >> b >> c; G[ a] [ b] = min ( G[ a] [ b] , c) ; } cout << Dijkstra ( 1 ) ; return 0 ;
}
邻接表版
const int N = 1e5 + 10 , INF = 0x3f3f3f3f ;
int h[ N] , e[ N] , ne[ N] , w[ N] , n, m, idx = 0 , d[ N] ;
bool visited[ N] ;
void add ( int a, int b, int c)
{ e[ idx] = b; ne[ idx] = h[ a] ; w[ idx] = c; h[ a] = idx++ ;
}
int Dijkstra ( int s)
{ fill ( d, d + N, INF) ; d[ s] = 0 ; for ( int i = 1 ; i <= n; ++ i) { int u = - 1 ; for ( int j = 1 ; j <= n; ++ j) if ( visited[ j] == false && ( u == - 1 || d[ j] < d[ u] ) ) u = j; visited[ u] = true ; for ( int v = h[ u] ; v != - 1 ; v = ne[ v] ) { int j = e[ v] ; if ( visited[ j] == false && w[ v] + d[ u] < d[ j] ) d[ j] = w[ v] + d[ u] ; } } return d[ n] == INF ? - 1 : d[ n] ;
} int main ( )
{ fill ( h, h + N, - 1 ) ; cin >> n >> m; for ( int i = 0 ; i < m; ++ i) { int a, b, c; cin >> a >> b >> c; add ( a, b, c) ; } cout << Dijkstra ( 1 ) ; return 0 ;
}