Dijkstra最短路算法

dijkstra实际上用的是贪心算法,基本概念为

如果一个点到另外一个点最短线为X ,那么无论怎么绕路都比他之和大

 恶搞代码:

#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 : 前面贪心是是否已固定此点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值