机试算法讲解: 第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
原创粉丝点击