Dijkstra算法实现==2014hiho第23周最短路问题
来源:互联网 发布:12306购票软件下载 编辑:程序博客网 时间:2024/05/15 18:44
- 样例输入
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 )
描述
万圣节的早上,小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为了走出鬼屋至少要走的路程。
- Dijkstra算法实现==2014hiho第23周最短路问题
- POJ 1847 最短路问题 dijkstra算法的实现
- [图论]最短路问题 dijkstra算法
- 最短路问题——Dijkstra算法
- 最短路问题 (Dijkstra 迪杰斯特拉算法)
- 优先队列Dijkstra实现最短路算法
- 算法:Python实现dijkstra最短路由
- hdu2544(Dijkstra算法最短路问题)最短路
- 最短路 Dijkstra算法
- 最短路算法Dijkstra
- Dijkstra最短路算法
- 最短路,dijkstra算法。
- 最短路-Dijkstra算法
- 最短路 Dijkstra算法
- 最短路 Dijkstra算法
- Dijkstra最短路算法
- 最短路-Dijkstra算法
- Dijkstra最短路算法
- 【BZOJ 1636】 [Usaco2007 Jan]Balanced Lineup
- iOS进阶面试题----经典10道
- IOS中设置UINavigationBar的各种样式(图片/透明效果/下方内容显示情况)
- 学习scala-hello-world!
- Struts2 自定义Result
- Dijkstra算法实现==2014hiho第23周最短路问题
- 循环嵌套的时间复杂度分析
- Google 的厕所内测文化
- linux 各种配置教程
- 【C语言第十六回合】:文件函数大锅饭
- 推荐一个Linux远程桌面工具
- centos 6.5 安装gitlab安装需注意的问题
- 1111111
- C/C++ struct初始化/复制/内存分配技巧