dijkstra实际上用的是贪心算法,基本概念为
如果一个点到另外一个点最短线为
,那么无论怎么绕路都比他之和大
恶搞代码:
#include<bits/stdc++.h>
using namespace std;
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#ifdef abs
#undef abs
#endif
#ifdef isdigit
#undef isdigit
#endif
#ifdef isalpha
#undef isalpha
#endif
#ifdef MAXN
#undef MAXN
#endif
#define min(a,b) ( a < b ? a : b )
#define max(a,b) ( a > b ? a : b )
#define abs(a) ( a < 0 ? ~a - 1 : a )
#define isdigit(ch) ( ch >= 48 && ch <= 57 )
#define isalpha(ch) ( ( ch >= 97 && ch <= 122 ) || ( ch >= 65 && ch <= 90 ) )
#define MAXN 20010
int dis [ MAXN ] , i , j , VS , Spot , Dont_move_spot ,
x , y , z ;
int const * X = &x ,
* Y = &y ,
* Z = &z ;
vector < int > Edge [ MAXN ] ;
vector < int > Base [ MAXN ] ;
bitset < MAXN > Gd ;
inline int
__fastcall Min_of (
int
* a ,
int
n ) {
int Min = a [ 1 ] ;
int idx = 1 ;
for ( i = 2 ; i <= n ; ++i ) if ( a [ i ] < Min ) Min = a [ i ] , idx = i ;
return idx ;
}
inline void
__fastcall
Dijstra (
int
n
)
{
dis [ 1 ] = 0 ;
for ( i = 0 ; i < n ; ++i ) {
Dont_move_spot = Min_of ( dis , n ) ;
VS = Edge [ Dont_move_spot ].size( ) ;
for ( j = 0 ; j < VS ; ++j ) {
Spot = Edge [ i ] [ j ] ;
if (
Gd [ Spot ]
)
continue ;
if ( dis [ Spot ]
>= dis [ i ]
+
Base [ i ] [ j ]
)
dis [ Spot ] = dis [ i ] +
Base [ i ] [ j ] ;
}
Gd [ Dont_move_spot ] =
true ;
}
}
int q , n , m ;
int main( void
) {
/*read*/
memset ( &Gd , false , sizeof ( Gd ) ) ;
scanf (
"%d%d%d" ,
&n ,
&m ,
&q
) ;
for ( i = 0 ;
i < q ;
++i )
scanf ( "%d%d%d"
, X
, Y
, Z
) ,
Edge[
x
].push_back(
y
) ,
Edge[
y
].push_back(
x
) ,
Base[
x
].push_back(
y
) ,
Base[
y
].push_back(
x
) ;
Dijstra (
n
)
;
for (
i = 0 ;
i < n ;
++i
)
printf (
"%d " ,
dis [
i
]
)
;
return 0;
}
#undef min
#undef max
#undef abs
#undef isdigit
#undef isalpha
格式化后:
#include<bits/stdc++.h>
using namespace std;
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#ifdef abs
#undef abs
#endif
#ifdef isdigit
#undef isdigit
#endif
#ifdef isalpha
#undef isalpha
#endif
#ifdef MAXN
#undef MAXN
#endif
#define min(a,b) ( a < b ? a : b )
#define max(a,b) ( a > b ? a : b )
#define abs(a) ( a < 0 ? ~a - 1 : a )
#define isdigit(ch) ( ch >= 48 && ch <= 57 )
#define isalpha(ch) ( ( ch >= 97 && ch <= 122 ) || ( ch >= 65 && ch <= 90 ) )
#define MAXN 20010
int dis [ MAXN ] , i , j , VS , Spot , Dont_move_spot ,
x , y , z ;
int const * X = &x ,
* Y = &y ,
* Z = &z ;
vector < int > Edge [ MAXN ] ;
vector < int > Base [ MAXN ] ;
bitset < MAXN > Gd ;
inline int
__fastcall Min_of (
int
* a ,
int
n ) {
int Min = a [ 1 ] ;
int idx = 1 ;
for ( i = 2 ; i <= n ; ++i ) if ( a [ i ] < Min ) Min = a [ i ] , idx = i ;
return idx ;
}
inline void
__fastcall
Dijstra (
int
n
) {
dis [ 1 ] = 0 ;
for ( i = 0 ; i < n ; ++i ) {
Dont_move_spot = Min_of ( dis , n ) ;
VS = Edge [ Dont_move_spot ].size( ) ;
for ( j = 0 ; j < VS ; ++j ) {
Spot = Edge [ i ] [ j ] ;
if (
Gd [ Spot ]
)
continue ;
if ( dis [ Spot ]
>= dis [ i ]
+
Base [ i ] [ j ]
)
dis [ Spot ] = dis [ i ] +
Base [ i ] [ j ] ;
}
Gd [ Dont_move_spot ] =
true ;
}
}
int q , n , m ;
int main( void
) {
/*read*/
memset ( &Gd , false , sizeof ( Gd ) ) ;
scanf (
"%d%d%d" ,
&n ,
&m ,
&q
) ;
for ( i = 0 ;
i < q ;
++i )
scanf ( "%d%d%d"
, X
, Y
, Z
) ,
Edge[
x
].push_back(
y
) ,
Edge[
y
].push_back(
x
) ,
Base[
x
].push_back(
y
) ,
Base[
y
].push_back(
x
) ;
Dijstra (
n
)
;
for (
i = 0 ;
i < n ;
++i
)
printf (
"%d " ,
dis [
i
]
)
;
return 0;
}
#undef min
#undef max
#undef abs
#undef isdigit
#undef isalpha
base : 边 ,
edge:可到达点
base和edge一起加减,一一对应(pair < int ,
int >
);
Gd : 前面贪心是是否已固定此点