zoukankan      html  css  js  c++  java
  • 从某个源点到指定地点的最短路径(迪杰斯特拉算法的实现)

    // algo7-6.cpp 实现算法7.15的程序。迪杰斯特拉算法的实现
    #include"c1.h"
    #define MAX_NAME 5 // 顶点字符串的最大长度+1
    #define MAX_INFO 20 // 相关信息字符串的最大长度+1
    typedef int VRType;
    typedef char InfoType;
    typedef char VertexType[MAX_NAME];
    #include"c7-1.h" // 邻接矩阵存储结构
    #include"bo7-1.cpp" // 邻接矩阵存储结构的基本操作
    typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 路径矩阵,二维数组
    typedef int ShortPathTable[MAX_VERTEX_NUM]; // 最短距离表,一维数组
    void ShortestPath_DIJ(MGraph G,int v0,PathMatrix P,ShortPathTable D)
    { // 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度
    	// D[v]。若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。
    	// final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径算法7.15
    	int v,w,i,j,min;
    	Status final[MAX_VERTEX_NUM]; // 辅助矩阵,为真表示该顶点到v0的最短距离已求出,初值为假
    	for(v=0;v<G.vexnum;++v)
    	{
    		final[v]=FALSE; // 设初值
    		D[v]=G.arcs[v0][v].adj; // D[]存放v0到v的最短距离,初值为v0到v的直接距离
    		for(w=0;w<G.vexnum;++w)
    			P[v][w]=FALSE; // 设P[][]初值为FALSE,没有路径
    		if(D[v]<INFINITY) // v0到v有直接路径
    			P[v][v0]=P[v][v]=TRUE; // 一维数组p[v][]表示源点v0到v最短路径通过的顶点
    	}
    	D[v0]=0; // v0到v0距离为0
    	final[v0]=TRUE; // v0顶点并入S集
    	for(i=1;i<G.vexnum;++i) // 其余G.vexnum-1个顶点
    	{ // 开始主循环,每次求得v0到某个顶点v的最短路径,并将v并入S集
    		min=INFINITY; // 当前所知离v0顶点的最近距离,设初值为∞
    		for(w=0;w<G.vexnum;++w) // 对所有顶点检查
    			if(!final[w]&&D[w]<min) //在S集之外的顶点中找离v0最近的顶点,并将其赋给v,距离赋给min
    			{
    				v=w;
    				min=D[w];
    			}
    			final[v]=TRUE; // 将v并入S集
    			for(w=0;w<G.vexnum;++w) // 根据新并入的顶点,更新不在S集的顶点到v0的距离和路径数组
    				if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&(min+G.arcs[v][w].adj<D[w]))
    				{ // w不属于S集且v0→v→w的距离<目前v0→w的距离
    					D[w]=min+G.arcs[v][w].adj; // 更新D[w]
    					for(j=0;j<G.vexnum;++j) // 修改P[w],v0到w经过的顶点包括v0到v经过的顶点再加上顶点w
    						P[w][j]=P[v][j];
    					P[w][w]=TRUE;
    				}
    	}
    }
    void main()
    {
    	int i,j;
    	MGraph g;
    	PathMatrix p; // 二维数组,路径矩阵
    	ShortPathTable d; // 一维数组,最短距离表
    	CreateDN(g); // 构造有向网g
    	Display(g); // 输出有向网g
    	ShortestPath_DIJ(g,0,p,d);//以g中位置为0的顶点为源点,球其到其余各顶点的最短距离。存于d中
    	printf("最短路径数组p[i][j]如下:
    ");
    	for(i=0;i<g.vexnum;++i)
    	{
    		for(j=0;j<g.vexnum;++j)
    			printf("%2d",p[i][j]);
    		printf("
    ");
    	}
    	printf("%s到各顶点的最短路径长度为
    ",g.vexs[0]);
    	for(i=0;i<g.vexnum;++i)
    		if(i!=0)
    			printf("%s-%s:%d
    ",g.vexs[0],g.vexs[i],d[i]);
    }

    代码的运行结果:

    请输入有向网G的顶点数,弧数,弧是否含其它信息(是:1,否:0): 6,8,0(见图768)
    请输入6个顶点的值(<5个字符):
    V0 V1 V2 V3 V4 V5
    请输入8条弧的弧尾弧头权值(以空格作为间隔):
    V0 V5 100
    V0 V4 30
    V0 V2 10
    V1 V2 5
    V2 V3 50
    V3 V5 10
    V4 V3 20
    V4 V5 60
    6个顶点8条边或弧的有向网。顶点依次是: V0 V1 V2 V3 V4 V5
    G.arcs.adj:
    32767 32767 10 32767 30 100
    32767 32767 5 32767 32767 32767
    32767 32767 32767 50 32767 32767
    32767 32767 32767 32767 32767 10
    32767 32767 32767 20 32767 60
    32767 32767 32767 32767 32767 32767
    G.arcs.info:
    顶点1(弧尾) 顶点2(弧头) 该边或弧的信息:
    最短路径数组p[i][j]如下:
    0 0 0 0 0 0
    0 0 0 0 0 0
    1 0 1 0 0 0
    1 0 0 1 1 0
    1 0 0 0 1 0
    1 0 0 1 1 1

    V0到各顶点的最短路径长度为
    V0-V1:32767
    V0-V2:10
    V0-V3:50
    V0-V4:30
    V0-V5:60


    函数ShortestPath_DIJ()利用2 个辅助数组final[]和D[]求得给定点v0 到图G 中其余
    各顶点的最短距离。D[]存放当前v0 到其余各顶点的最短距离,final[]的初值为FALSE。
    final[]的值为TRUE,表示v0 到该顶点的最短距离已求出。图769 通过final[]和D[]的
    变化演示了求解过程。

    首先,final[]的初值中只有final[v0]为真,最短距离顶点集S 中只有顶点v0(源点,
    此例中实参为V0)。D[]的初值是邻接矩阵中v0 行所对应的值。另令D[v0]=0(v0 到自己
    的距离当然为0)。v0 到某顶点i 的最短距离可能是二者的直接距离G.arcs[v0][i].adj,也
    可能是由v0 出发,经过其它顶点,最后到达顶点i 的距离。如图768 中V0 到V5 的最
    短距离不是它们的直接距离100,而是由V0 经过V4、V3,最后到达V5 的距离60。
    根据图769(a),在不属于S 集的顶点中,V0 到V2 的距离最短。可以断定,V0 到
    V2 的距离10 是最短距离。V0 通过其它顶点绕道到达V2 的距离一定会比10 大,故将V2
    并入S 集中(final[2]=TRUE)。并考察S 集外的顶点中,有没有哪个顶点i,使得V0 先到
    V2(距离为10),再由V2 到达顶点i 比直接从V0 到达顶点i 的距离要小?也就是满足
    10+G.arcs[2][i].adj<D[i]。如有,则改写D[i]。V0 本无直接到达V3 的路径,但有V0
    →V2→V3 的路径,为10+G.arcs[2][3].adj=10+50=60,故改写D[3]=60,如图769(b)
    所示。用这样的方法,依次将V4、V3 和 V5 并入S。详见图769(c)、(d)和(e)。
    通过final[]和D[]可求得给定点v0 到图G 中其余各顶点的最短距离是多少。但却不
    知道其间通过哪些顶点。矩阵P[][]有这些顶点的信息。以程序运行结果为例,1 维数组
    p[2][]中的1 是V0 到V2 经过的顶点(只有V0 和V2 两个顶点);p[3][]中的1 是V0 到
    V3 经过的顶点(V0、V3 和V4)。

  • 相关阅读:
    2020杭电HDU-6831多校第六场Fragrant numbers(区间DP打表)
    Gym 102219H-Are You Safe?(凸包求解+判断点与凸包关系)
    2020杭电HDU-6827多校第六场Road To The 3rd Building(找规律求期望)
    洛谷P1099&Noip 2007提高-树网的核(树直径上的尺取)
    2020杭电HDU-6832多校第六场A Very Easy Graph Problem(最短路转最小生成树+dfs)
    CodeForces 950D-A Leapfrog in the Array(打表找规律)
    使用odoo价格表[pricelist]对价格进行特别处理,如 .99
    odoo 10 生产自动领料
    安装odoo服务
    advanced validation on purchase.
  • 原文地址:https://www.cnblogs.com/KongkOngL/p/4074448.html
Copyright © 2011-2022 走看看