Dijkstra算法实现==2014hiho第23周最短路问题

来源:互联网 发布:12306购票软件下载 编辑:程序博客网 时间:2024/05/15 18:44

题目:最短路径

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

万圣节的早上,小Hi和小Ho在经历了一个小时的争论后,终于决定了如何度过这样有意义的一天——他们决定去闯鬼屋!

在鬼屋门口排上了若干小时的队伍之后,刚刚进入鬼屋的小Hi和小Ho都颇饥饿,于是他们决定利用进门前领到的地图,找到一条通往终点的最短路径。

鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路。那么小Hi和小Ho至少要走多少路程才能够走出鬼屋去吃东西呢?

       

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为4个整数N、M、S、T,分别表示鬼屋中地点的个数和道路的条数,入口(也是一个地点)的编号,出口(同样也是一个地点)的编号。

接下来的M行,每行描述一条道路:其中的第i行为三个整数u_i, v_i, length_i,表明在编号为u_i的地点和编号为v_i的地点之间有一条长度为length_i的道路。

对于100%的数据,满足N<=10^3,M<=10^4, 1 <= length_i <= 10^3, 1 <= S, T <= N, 且S不等于T。

对于100%的数据,满足小Hi和小Ho总是有办法从入口通过地图上标注出来的道路到达出口。

输出

对于每组测试数据,输出一个整数Ans,表示那么小Hi和小Ho为了走出鬼屋至少要走的路程。

样例输入
5 23 5 41 2 7082 3 1123 4 7214 5 3395 4 9601 5 8492 5 981 4 992 4 252 1 2003 1 1463 2 1061 4 8604 1 7955 4 4795 4 2803 4 3411 4 6224 2 3622 3 4154 1 9042 1 7162 5 575
样例输出
123


在hiho上看到这道题,大学期间也学到过Dijkstra最短路径算法,但当时没学好,今天花了1个多小时重新看了一下,总算看明白,开心。

另外Dijkstra老爷子还是很不错的,前几天去笔试让写知道的计算机界有贡献的人,想了半天只写出图灵诺依曼,惭愧。

这里有一篇关于Dijkstra算法的文章,还有动图,推荐一下:

http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html


下面是我给出的算法的描述(感觉虽然没将算法原理讲清,但是便于实现):

1.初始化将起始点加入到S集合(默认其余的元素在U集合),选择起始点并设置dist[i],dist[i]表示i点到起始点的距离。

2.将U集合中点逐“1”加入到S集合中,加入规则:谁距离起始点最近谁加入S集合(mindist)。加入后更新dist数组重新设置各点到起始点距离。(eg:A为起始点且在S集合,B,C...在U集合,若AB=2(minA*),AC=无穷...BC=3,将B加入到S集合中后,由于AC>AB+BC,所以update dist[iC] = 5,对于U中其它元素同理)

3.重复步骤2直到S集合满。dist即最终结果集。


代码实现:

//dijkstra Ëã·¨Çó×î¶Ì·ÎÊÌâ //Ë㷨˵Ã÷£º/*   1.³õʼ»¯£¬Ñ¡¶¨³õʼµã²¢½«³õʼµã´æÈëS¼¯ºÏÖУ»    2.½«U¼¯ºÏÖеĵãÖð 1 ¼ÓÈëÖÁS¼¯ºÏÖУ¬¼ÓÈë¹æÔò£ºË­µ½Æðʼµã¾àÀë×î½ü¾Í½«Ë­¼ÓÈ룬¼ÓÈëºóÖØмÆÁ¿U¼¯ºÏÖеĵ㵽ÆðʼµãµÄ¾àÀ룻       (È磺³õʼµãΪA£¬¼¯ºÏSÖе±Ç°Ö»´æÔÚA£¬¼¯ºÏUÖÐÓÐB,CÈô¸É¸öµã£¬AB£¨A*ÖÐ×îСµÄ£©=2£¬AC=ÎÞÇBC=3£¬¸ù¾Ý¹æÔòBµã¼ÓÈ뼯ºÏSºó£¬ÓÉÓÚAC>AB+BC, ËùÒÔAC±»ÖØÖÃΪ5)    3.Öظ´¶þ£¬Ö±µ½È«²¿µã±»¼ÓÈëµ½S¼¯ºÏΪֹ£»    add:¹Ø¼üÊý¾Ý½á¹¹£¬Í¼µÄ¼Ç¼¶þάÊý×émap                     Ç°Çý¼Ç¼һλÊý×éprev ¾àÀë¼Ç¼һάÊý×édist s¼¯ºÏ±êʶÊý×ésMem s¼¯ºÏÊý¾ÝÊýÁ¿ */ #include<stdio.h>long map[1002][1002] ; //map[i][j]¼Ç¼iµ½jµãµÄ¾àÀë long dist[1002] ; //dist[i]¼Ç¼iµ½Ô­µãµÄ×î¶Ì¾àÀë int sMem[1002]; //ÈôÔªËØiÔÚ¼¯ºÏSÖУ¬ÔòsMem[i] = 1; ·ñÔòsMem = 0 int sNum; //¼¯ºÏSÖÐÔªËصÄÊýÁ¿ long Dijkstra( int v0,int v1,int N ) ;int main(){    int N , M , S , T ;    int i , j , k ;    long l ;    scanf( "%d %d %d %d" , &N,&M,&S,&T ) ;        for( i=1;i<=N;i++ )    {    for( j=1;j<=N;j++ )    {    if(i==j)        map[i][j] = 0 ;    else    map[i][j] = 100000000 ;    }}i = 1 ;while( i<=M ){    i++ ;    scanf("%d %d %ld",&j,&k,&l) ;    if( map[j][k] > l )    map[j][k] = l ;     if( map[k][j] > l )        map[k][j] = l ; }printf("%ld\n",Dijkstra( S,T,N )) ;system("pause") ;     return 0 ;}//int main()long Dijkstra( int v0,int v1,int N ){    int i ;     int j ;    long mindist ;    int target ;/*for( i=1 ; i<= 100 ; i++ ){    prev[i] = -1 ;}prev[v0] = 0 ;//³õʼ»¯Ç°Çý½ÚµãÊý×é */for( i=1;i<=N;i++ )    {    sMem[i] = 0 ;}sMem[v0] = 1 ; //³õʼ»¯¼Ç¼¼¯ºÏS sNum = 1 ;//³õʼ»¯¼¯ºÏSÊýÁ¿for( i=1 ;i<=N; i++ ) {    dist[i] = map[v0][i] ;}while(sNum<N){mindist = 100000001 ;    for( i=1;i<=N;i++ )    {    if( (!(sMem[i])) && dist[i] < mindist )    {    target = i ; //iµãÊÇU¼¯ºÏÖоàÀëÔ­µã×î½üµÄµã     mindist = dist[i] ;}}        sMem[target] = 1 ;sNum++ ;for( i=1 ; i<=N ; i++ ){    if((!(sMem[i])) && (dist[i]>dist[target]+map[target][i]) )        dist[i] = dist[target]+map[target][i] ;}}return dist[v1] ;}//long Dijkstra( int v0,int v1,int N )

                                                                                                                                                                        

0 0
原创粉丝点击