机试算法讲解: 第37题 Dijkstra
来源:互联网 发布:mac jenkins 安装 编辑:程序博客网 时间:2024/06/11 18:34
/*Dijkstra:单源最短路径。第m+1近的结点与结点1的最短路径上的中间节点一定属于集合K,任意最短路径中间有一个不属于集合K的节点,则它的最短路径距离一定<第m+1近的节点的最短路径长度,与距离与第m+1近的节点的最短路径已经确定、这样的结点属于集合K相矛盾。最短路径 = 从结点1出发经最短路径集合中K中的节点P2 + <p2,Vn>算法流程:1)初始化,在集合K中加入结点1,结点1到结点1的最短距离为0,到其他结点距离为无穷大2)遍历与集合K中结点直接相邻的边(U,V,C),其中U属于集合K,V不属于集合K,计算从结点1出发,按照已经得到的最短路径到达U,再由U经过该边到达V的路径长度。比较所有与集合K中直接相邻的非集合K中结点的路径长度,路径长度最小的节点为下一个确定节点,将该结点加入集合K3)若集合K中含有所有节点,结束先更新距离,后挑选路径最短的节点加入,对于已经加入的节点需要直接跳过,通过vector来构建单链表*/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <vector>#define MAX 100using namespace std;typedef struct Edge{int _iNext;//下一个节点编号int _iDistance;//从当前节点到下一个节点之间的距离}Edge;bool Mark[MAX];//标记是否已经是在已知节点集合int Dist[MAX];//距离向量,为true表示最短记录。否则,表示经过中间节点的最短距离int main(int argc){int n,m,i,j,iVi,iVj,iDis;vector<Edge> vecEdge[MAX];//用了100个数组,每个数组用来存放单链表信息while(EOF!=scanf("%d %d",&n,&m)){//易错,n和m都为0的时候要退出if(0==n && 0==m){break;}//易错,要初始化邻接链表for(i = 1 ; i <=n ; i++){vecEdge[i].clear();}//获取每条边的信息for(i = 0 ; i < m ; i++){scanf("%d %d %d",&iVi,&iVj,&iDis);//要构造一个结构体Edge edge,edge2;edge._iNext = iVj;edge._iDistance = iDis;edge2._iNext = iVi;edge2._iDistance = iDis;//由于是无向图,所以需要添加2条边vecEdge[iVi].push_back(edge);vecEdge[iVj].push_back(edge2);}//初始化for(int i = 1 ; i < MAX; i++){Mark[i] = false;Dist[i] = -1;}Dist[1] = 0;//设置节点1的长度为0Mark[1] = true;//设置节点1为已经加入集合//易错,需要设置一个新节点int iNewP = 1;//遍历n-1趟,先更新距离,再挑选最短距离for(i = 1 ; i < n ; i++){for(j = 0 ; j < vecEdge[iNewP].size(); j++)//for(j = 1 ; j < vecEdge[iNewP].size() ; j++)//遍历vector必须从0开始遍历{//取出边,判断与其相连的节点是否已经被标记int iNext = vecEdge[iNewP][j]._iNext;int iWeight = vecEdge[iNewP][j]._iDistance;//如果已经属于集合K,则跳过//if(iNext==true)if(Mark[iNext]==true){continue;}//如果距离不可达 或者走新加入节点的路径距离更短时,更新距离if(Dist[iNext]==-1 || Dist[iNewP] + iWeight < Dist[iNext]){Dist[iNext] = Dist[iNewP] + iWeight;}}//选择距离最短的结点,遍历所有节点int min = 123123123;for(j = 1 ; j <= n;j++){//若其属于集合K,节点不可达,则跳过if(Mark[j]==true || -1==Dist[j]){continue;}if(Dist[j] < min){min = Dist[j];iNewP = j;//更新加入的结点}}//设置新加入的节点标记Mark[iNewP] = true;}printf("%d\n",Dist[n]);}system("pause");getchar();return 0;}
0 0
- 机试算法讲解: 第37题 Dijkstra
- 机试算法讲解: 第38题 求Dijkstra最短路径及花费
- Dijkstra算法模拟讲解
- Dijkstra算法详细讲解
- 机试算法讲解: 第15题 霍夫曼树是啥树啊?
- 机试算法讲解: 第21题 再谈进制转换
- 机试算法讲解: 第23题 哦,最小公倍数
- 机试算法讲解:第26题 分解素因数
- 机试算法讲解: 第27题 k次方整除
- 机试算法讲解:第32题 并查集是个好东西
- 机试算法讲解:第36题 Floyd
- 机试算法讲解: 第57题 位运算
- 机试算法讲解: 第58题 输入外挂
- 机试算法讲解:第20题 一起重温小学题:进制转换
- 机试算法讲解:第24题 大水题:谁是素数?
- 机试算法讲解:第1题 冒泡排序与快速排序
- 机试算法讲解:第2题 结构体之快速排序
- 机试算法讲解: 第3题 求两个日期相差的天数
- Java NIO - 简介
- 机试算法讲解:第36题 Floyd
- 学习AngularJS的一些资料及网站
- PreparedStatement 预编译
- 敏捷开发Scrum
- 机试算法讲解: 第37题 Dijkstra
- ubuntu 如何创建新用户
- iOS alloc和new的区别与联系
- windows下如何将本地项目push到github仓库
- UVa 10340 All in All
- zedboard 8路拨码开关
- HDU 2128Tempter of the Bone II(bfs + 保存每一步的图)
- 【练习笔记】剑指offer-面试题6 :重建二义树
- 正则表达式