最小生成树算法之 Dijkstra算法

Dijkstra算法

Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是用来求任意两个顶点之间的最短路径。在该算法中,我们用邻接矩阵来存储图。在该程序中设置一个二维数组来存储任意两个顶点之间的边的权值。可以将任意一个图的信息通过键盘输入,让后在输入要查找的两个顶点,程序可以自动求出这两个顶点之间的最短路径。

算法思想

s为源,Map[u,v] 为点u 和v 之间的边的长度,结果保存在 dis[];

初始化:源的距离dis[s]设为0,其他的点距离设为无穷大,同时把所有的点状态设为没有扩展过。

循环n-1次:

1. 利用标记变量数组 在没有扩展过的点中取一距离最小的点u,并将其状态设为已扩展。

2. 对于每个与u相邻的点v,如果dis[u] + Map[u,v]  <  dis[v],那么把dist[v]更新成更短的距离dis[u] + Map[u,v] 。此时到点v的最短路径上,前一个节点即为u。

结束:此时对于任意的u,dist[u]就是s到u的距离。

附 Hdu 2544 最短路

做题思想

建立一个Map的二维数组 里面的初始值改为一个INF(大数) 把从A到B 的路径长度储存进去

建立一个Dis 的数组  储存Map[ s ][ 0 →n ]里的数据  循环N-1次 每次标记一个dis中最小的标号 并用

if(!flag[i] && dis[i]>dis[t] + Map[t][i]) 该标号更新Dis 数组

更新过后 dis[ x ] 即为源点S的到x 的最短距离

代码

#include<stdio.h>    // Dijkstra 算法
#include<iostream>
#include<string.h>
#define INF 10000000
using namespace std;
int Map[101][101],dis[110];
int n ,m;
void Dijkstra()
{
    int i,j,D = 0;
    bool flag[110];
    memset(flag,0,sizeof(flag));    //标记数组
    for(i=1; i<=n; i++)
        dis[i]=Map[1][i];           //与1处的距离  每一个i代表自身与1的距离
    for(i=1; i<n; i++)               //每次循环标记一个点   一共标记n-1个点
    {
        int temp = INF;
        for(j=1; j<=n; j++)       //找出dis数组中的最小的那个值 位置用D记录下来
            if(!flag[j]&&dis[j]<temp)
            {
                temp = dis[j];
                D = j;
            }
        flag[D] = 1;              //把该点标记
        for(j=1; j<=n; j++)       //更新dis数组   以D
        {
            if(!flag[j]&&dis[j] > Map[D][j]+dis[D])
                dis[j] = Map[D][j]+dis[D];
        }
    }
}
int main()
{
    int i,j,x,y,z;
    while(scanf("%d %d",&n,&m)!=EOF&&(m||n))
    {
        for(i=0; i<101; i++) {     //地图清空初始化为一个大数
            for(j=0; j<101; j++)
                Map[i][j] = INF;
        Map[i][i]=0;
        }
        for(i=1; i<=m; i++)
        {
            cin >> x >> y >> z;      //输入
            if(Map[x][y] > z)         //如果再次输入的 比之前的小,覆盖
                Map[x][y]=Map[y][x] = z;
        }
        Dijkstra();
        printf("%d\n",dis[n]);      //全部循环过后,dis【n】的值即为从1到n 的距离;
    }
    return 0;
}

附:

ACM假期集训感悟:

一转眼半个月过去了,上午听师哥讲算法,看书;下午刷题,总结;

别人都说我们程序员苦,累;还有一个绰号 “屌丝程序猿”;

可我并不这么认为,每天学习算法锻炼思维,刷题提高代码能力和逻辑思维

在ACM训练中,最开心的时候就是花老长时间去改错,WA一遍又一遍,终于该出了最后一个BUG ,AC!

心情就无比的舒畅,看窗外的树叶是那样的翠绿,天是那样的蔚蓝。

在大学生活中能过的如此充实,有动力,有目标,朝着目标一步一步的走去, 是多么幸福的一件事

在这里,送出我的一句话:

整个世界填满不了十八岁男孩子的雄心和梦。

最小生成树算法之 Dijkstra算法,布布扣,bubuko.com

时间: 2024-10-18 01:34:35

最小生成树算法之 Dijkstra算法的相关文章

数据结构与算法系列研究七——图、prim算法、dijkstra算法

图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph)表示的是顶点之间的邻接关系. (1) 无向图(undirect graph)      E中的每条边不带方向,称为无向图.(2) 有向图(direct graph)      E中的每条边具有方向,称为有向图.(3) 混合图       E中的一些边不带方向, 另一些边带有方向.(4) 图的阶      指

最短路径算法(Dijkstra算法、Floyd-Warshall算法)

最短路径算法具体的形式包括: 确定起点的最短路径问题:即已知起始结点,求最短路径的问题.适合使用Dijkstra算法. 确定终点的最短路径问题:即已知终结结点,求最短路径的问题.在无向图中,该问题与确定起点的问题完全等同:在有向图中,该问题等同于把所有路径方向反转的确定起点的问题. 确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径. 全局最短路径问题:求图中所有的最短路径.Floyd-Warshall算法. dijkstra算法思想: 开始时,S={u},T=V-{u}; 对

数据结构与算法——最短路径Dijkstra算法的C++实现

之前的讨论了无权图的最短路径算法.数据结构与算法--无权最短路径算法的C++实现 如果是加权图,那么问题就变得困难了,不过仍然可以采用无权情况的想法. 我们仍然保留之前的信息.因此,每个顶点会被标记为known或unknown,每个顶点保留一个尝试性的距离dv(这个距离是只使用一些known顶点作为中间顶点从s到v的最短路径的长),每个顶点还保留字段pv,该字段是记录引起dv变化的最后的顶点. 图顶点信息的数据结构: //保存每个顶点信息的数据结构 struct GraphNode{ bool

图中最短路径算法(Dijkstra算法)(转)

1.Dijkstra 1)      适用条件&范围: a)   单源最短路径(从源点s到其它所有顶点v); b)   有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图) c)   所有边权非负(任取(i,j)∈E都有Wij≥0); 2)      算法描述: 在带权图中最常遇到的问题就是,寻找两点间的最短路径问题. 解决最短路径问题最著名的算法是Djikstra算法.这个算法的实现基于图的邻接矩阵表示法,它不仅能够找到任意两点的最短路径,还可以找到某个指定点到其他

最短路径算法之Dijkstra算法(java实现)

前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知识准备: 1.表示图的数据结构 用于存储图的数据结构有多种,本算法中笔者使用的是邻接矩阵.  图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 从上面可以看出,无向图的边

【数据结构】拓扑排序、最短路径算法、Dijkstra算法、无环图等等

图的定义 图(graph)G = (V,E)由顶点(vertex)的集V和边(Edge)的集E组成.有时也把边称作弧(arc),如果点对(v,w)是有序的,那么图就叫做有向的图(有向图).顶点v和w邻接(adjacent)当且仅当(v,w)属于E. 如果无向图中从每一个顶点到其他每个顶点都存在一条路径,则称该无向图是连通的(connected).具有这样性质的有向图称为是强连通的(strongly connected).如果有向图不是强连通的,但它的基础图(underlying graph)(也

图论(三) (一)最短路径算法 2.Dijkstra算法

Dijkstra 算法解决的是带权重的有向图上单源最短路径问题,该算法要求所有边的权重都为非负值.该算法的时间复杂度是O(N2),相比于处理无负权的图时,比Bellmad-Ford算法效率更高. 算法描述: 首先引用<算法导论>中的一段比较官方的话,如果可以看懂,那下一部分就可以跳过了: "Dijkstra算法在运行过程中维持的关键信息是一组结点集合S.从源结点s到该集合中每个结点之间的最短路径已经被找到.算法重复从结点集 V - S 中算则最短路径估计的最小的结点 u ,将 u 加

求最短路径(Bellman-Ford算法与Dijkstra算法)

前言 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的.这时候,就需要使用其他的算法来求解最短路径,Bellman-Ford算法就是其中最常用的一个. 在网络路由中,RIP协议(距离向量路由算法)一般用Bellman-Ford算法,同时由于简单性所以也适用于分布式系统:但是它的复杂度是O(VE),比Dijkstra算法要慢上许多.而OSPF协议,链路状态分组创建的时候一般用Dijkst

Prim算法与Dijkstra算法的联系与区别

/* 图结构,邻接矩阵形式 */ ElemType nodes[n]; int edges[n][n]; prim_or_dijkstra( int index, bool usePrim ) /* 起点 */ { int dist[n] = { INF }; /* 从起点开始,到其他所有边的距离 */ int distIndex[n] = { -1 }; int visited[n] = { 0 }; int selected = index; /*选中的点 */ /* 初始化起点的可达边距离