• 迪科斯彻算法总结


                                                    最短路之~迪科斯彻算法

            迪科斯彻算法是由荷兰计算机科学家艾滋郝尔·戴克斯拉提出的。本算法使用广度优先搜索解决非负权有向图的单源最短路径问题。算法终于得到一个最短路径树。此算法经常使用于路由算法或者作为其它图算法一个子模块。本算法是用来找一个点到其它全部点之间的最短路径

            此算法中变量的使用:

                    map[][]二维数组记录两点之间的权值,比如map[i][j]存放i点到j点的权值。当作为有向图时,给出i,j须要存放的仅仅有一个map[][],但普通情况下都是用无向图,需存两个map[][],即map[i][j]=map[j][i]=权值。

                    dis[]一维数组存放各点到起点的最短距离。mark[]一维数组标记使用过的点。

           单源最短路:

           Ⅰ、从一个点出发到其它全部点的最短路径的长度

            Ⅱ、基本操作:松弛操作。

            Ⅲ、dis[j] > dis[vir] + map[vir][j]这种边(vir,j)成为紧的,能够对它进行松弛操作。

                     对全部点进行松弛操作的代码可參考:

                      for(int j = 1; j <= n; j++)

                       {

                                   if(dis[j] > dis[vir] + map[vir][j] && !mark[j])

                                   dis[j] = dis[vir] + map[vir][j];

                       }

           Ⅳ、最開始给每个点一个非常大的dis值,从dis[s] = 0;開始,不断给能够松弛的点进行松弛操作。直至求出全部点的最短路径。

          本算法要求图中不存在负权边。

    可证明:具有最小的dis[i]的点没有增加最短路时,此后的点无法松弛。所以每次均要寻找近期的点进行松弛操作。

    详细请參考代码:

    #include<stdio.h>
    #define INF 0x3f3f3f3f					//定义一个较大的值。用来初始化 
    int map[1010][1010];					//存放两点间的权值
    int dis[1010];							//存放各点距起点的距离
    int mark[1010];							//标记使用过的点
    int n,m;								//有n个点,编号为1~n,有m组数据 
    void dijkstra(int s)
    {
    	int vir,min;
    	for(int i=1;i<=n;i++)				//初始化标记数组和距离数组 
    	{
    		mark[i]=0;						//0表示未使用此点 
    		dis[i]=INF;
    	}
    	dis[s]=0;
    	for(int i=1;i<=n;i++)
    	{
    		min=INF;
    		for(int j=1;j<=n;j++)			//查找权值最小的点 
    		{
    			if(!mark[j]&&dis[j]<min)
    			{
    				min=dis[j];
    				vir=j;
    			}
    		}
    		if(min==INF)	break;			//若没查找到或已查找完成。跳出 
    		mark[vir]=1;					//将查找到的点标记 
    		for(int j=1;j<=n;j++)			//将未查找到并可松弛的点进行松弛操作 
    		{
    			if(!mark[j]&&dis[j]>dis[vir]+map[vir][j])
    			dis[j]=dis[vir]+map[vir][j];
    		}
    	}
    }
    int main()
    {	
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		for(int i=1;i<=n;i++)			//初始化map数组 
    			for(int j=1;j<=n;j++)
    				map[i][j]=INF;
    		for(int i=0;i<m;i++)
    		{
    			int x,y,d;
    			scanf("%d%d%d",&x,&y,&d);	//输入两点及权值 
    			if(map[x][y]>d)				//若有反复。取较短的 
    			{
    				map[x][y]=d;
    				map[y][x]=d;
    			}
    		}
    		int start,end;
    		scanf("%d%d",&start,&end);		//输入起点和终点 
    		dijkstra(start);				//调用迪科斯彻算法 
    		printf("%d
    ",dis[end]);		//输出起点与终点间最短距离 
    	} 
    	return 0;
    } 


     

     

  • 相关阅读:
    .net c# gif动画如何添加图片水印
    Webbrowser控件设置所使用的内核
    WPF 用户控件不显示标记
    Spark应用场景以及与hadoop的比较
    Spark基本函数学习
    uniapp H5发布后在部分手机字体变大,导致页面错乱
    uni 小程序图片路径转base64
    uniapp px与upx(rpx)相互转换
    uniapp调用扫码功能
    uniapp 引入第三方字体
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7128171.html
Copyright © 2020-2023  润新知