Dijkstra算法

    xiaoxiao2023-11-05  134

    一、代码

    // // Created by dgm on 19-4-3. // #include <iostream> using namespace std; #define Maxnum 100 #define Infinity 65535 typedef int Vertex; typedef int ARType; typedef char* Info; typedef struct { ARType adj=Infinity; //边长 Info info; }Arcs[Maxnum][Maxnum]; //arcs[i][j]表示顶点i到j的边长 typedef struct { Arcs arcs; Vertex vexs[Maxnum];//顶点编号,简单起见,从0开始编号 int arcnum,vexnum; }MGraph; void CreateMGraph(MGraph&G) { cin>>G.vexnum>>G.arcnum; //顶点数和边数 for (int i = 0; i < G.vexnum; ++i) cin>>G.vexs[i]; int posx,posy,weight; //边的起点终点和权值 for (int i = 0; i < G.arcnum; ++i) { cin>>posx>>posy>>weight; G.arcs[posx][posy].adj=weight; } } typedef int PathMatrix[Maxnum][Maxnum]; typedef int ShortPathTable[Maxnum]; void ShortestPath_Dijkstra(MGraph G,int v0,PathMatrix&P,ShortPathTable&D) { //D[i]表示从v0到i的最短路径长度, //P[j][w]=1表示顶点w位于从v0到j的最短路径上 bool final[Maxnum];//final[j]=true表示从v0到j的最短路径已经建立 int v; for (int i = 0; i < G.vexnum; ++i) { final[i]= false; D[i]=G.arcs[v0][i].adj;//初始化v0到各顶点的距离 for (int j = 0; j < G.vexnum; ++j) P[i][j]=0;//初始化路径 if(D[i]<Infinity)//如果v0与i之间有边 { P[i][v0]=1;P[i][i]=1;//暂时建立路径v0->i(接下来会根据路径长短更新) } } final[v0]= true;D[v0]=0;//v0到v0的最短路径是0 for (int i = 1; i < G.vexnum; ++i) { int min=Infinity; for (int j = 0; j < G.vexnum; ++j) { if (!final[j]&&(D[j]<min)){ min=D[j];v=j;//找到距离v0最近且未加入最短路径的那个点,用v记录下来 } } final[v]=true;//将v加入最短路径 for (int j = 0; j < G.vexnum; ++j) {//建立v0与v的最短路径后, // 更新v0到尚未与v0建立最短路径的各点的距离(最短距离) if (!final[j]&&(min+G.arcs[v][j].adj<D[j])) { D[j]=min+G.arcs[v][j].adj;//如果v0->v->j的长度小于v0->j //那么从v0到j的路径更新为从v0到v的路径+从v到j的路径 for (int k = 0; k < G.vexnum; ++k) P[j][k]=P[v][k]; P[j][j]= 1; } } }//for循环一次,就会建立一条v0到其他顶点的最短路径, // final一直在变化,当所有顶点的final值都为true时,到每一个顶点的最短路径也就建立了 } int main() { MGraph G; CreateMGraph(G); ShortPathTable D; PathMatrix P; ShortestPath_Dijkstra(G,0,P,D); for (int i = 0; i < G.vexnum; ++i) { cout<<i<<": "; for (int j = 0; j < G.vexnum&&j!=i; ++j) //P[i][j]=1表示j在从v0到i的最短路径上 if (P[i][j]==1) cout<<j<<"->"; cout<<i<<" "; cout<<"shortest path: "<<D[i]<<endl; } return 0; }

    输入及输出:

    二、过程

    总结

    dijkstra算法与prim算法非常相似: prim算法是不断寻找U中与集合S之间距离最小的顶点加入S中(相当于集合与集合的最小距离),而dijsktra算法是不断寻找U中与集合S中的v0顶点之间距离最小的顶点加入S中(相当于点与集合的最小距离)。个人认为主要的两步是:①、找U(不属于最小生成树/最短路径集合的顶点)中距离(S/v0)最小的顶点并加入到S中;②、更新S/v0到U中其余点的距离。

    最新回复(0)