Dijkstra求最短路问题:单元求最短路,从任意点出发求得该点到达其他任意点的距离

Dijkstra其实是一种贪心策略,与出发点(即源点)所连接的点中找到距离最短的点(这个距离是源点到这个点的最短距离)再以这个点继续以这样的操作来找到最短距离的点(松弛操作)

Q:为什么离源点最近的那个节点与源点的连边是源点到那个节点的最短距离?

如下图:

A:根据图片我们可以得知如果这条边是源点到达该点的最短距离那一定是源点到达该点的最短距离,不管怎么用其他边去更新它都不如该边短.

Q:Dijkstra的贪心流程:

这里我们假设源点为点1.  节点间的距离为X(数字)。

由分步图我们可以得知与源点1相连的有点2和点3    这里我们就会有两个操作   1.确立源点的最短点;   2.松弛另一个或几个点.

由X(2),X(3)可以到达源点1 因为X(1—2)=1<X(1—3)=12,所以我门可以确定源点1到点2的最短距离为“1”  且  松弛点3即 dis[3]=12

这步我们可以获得 dis[2]=1(确定) dis[3]=12(未确定)。

下一步我们移步到点2(因为点2到源点的最短距离确定了因此由点2一定能更新出另一个最短点)由图得与点2相连的点有点3和点4,  因为X(2—3)=9>X(2—4)=3

所以同样的操作我们可以 确定点2到点4的距离为3,因为先前X(1—2)=1,X(2—4)=3所以X(1—4)=4(确定); 通过比较我们发现还可以松弛点3 X(1—3)=12>[X(1—2)=1+X(2—3)=9]即X(1—3)=10(未确定)

这步我们可以获得 dis[4]=4(确定) dis[3]=10(未确定)

步骤接下来也如此直到将n个节点全部进行n次操作那源点到每个节点的距离就确定了

代码:
DIjkstra部分:

void dijkstra()
{
for(int k=;k<=n;k++)
{
int minn=INF,pos;//贪心确定松弛点,并确定松弛点的坐标
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)
minn=dis[i],pos=i;//pos为松弛点的坐标,minn为源点到松弛点的值
}
vis[pos]=true;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]>dis[pos]+edges[pos][i])//更新dis值
dis[i]=dis[pos]+edges[pos][i];
}
}
return;
}

代码解释

先由源点松弛节点再在被松弛的节点中找到最小的距源点最短点作为下一个松弛点且确定此点到源点的距离最短下次不需要再被松弛因此将此点vis[pos]=true;不必再对此点进行操作

第一部分:

for(int k=;k<=n;k++)
{
int minn=INF,pos;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)
minn=dis[i],pos=i;
}

//pos为此松弛点的坐标 minn为此松弛点的值
//此部分代码目的为找到下一个松弛点并确定松弛点到源点的值
//dis[松弛点]确定不再改变因此我们需要将vis[pos]=true
//dis[松弛点]==minn确定并为下一步松弛记录坐标pos

第二部分:

for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]>dis[pos]+edges[pos][i])
dis[i]=dis[pos]+edges[pos][i];
}
//由于上一步将松弛点vis[pos]=true因此在此操作中if(!vis[i])即排除松弛点
//并枚举1~n中可以被松弛的点,并对其进行松弛即dis[i]=dis[pos]+edges[pos][i]

关于dis[ i ]=dis[pos]+edges[pos][ i ]的解释

dis[pos]为松弛点在第一部分我们可以确定它的值,edges[pos][i]在输入时可以确定其值

所以当dis[i]>dis[pos]+edges[pos][i]时我们便可以松弛这个点的值即可以求得dis[源点—i]的值

整体代码:

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstring>
using namespace std;
typedef int insert;
#define in cin
#define out cout
const int INF=0x3f3f3f3f;
const int N=+;
insert n,m,x,y,z,dis[N],vis[N],edges[N][N];
insert startpoint; void value()
{
memset(edges,INF,sizeof(edges));
memset(dis,INF,sizeof(dis));
for(int i=;i<=m;i++)
{
in>>x>>y>>z;
edges[x][y]=z;
}
dis[startpoint]=;
return;
} void dijkstra()
{
for(int k=;k<=n;k++)
{
insert minn=INF,pos;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)
minn=dis[i],pos=i;
}
vis[pos]=true;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]>dis[pos]+edges[pos][i])
dis[i]=dis[pos]+edges[pos][i];
}
}
return;
}
int main()
{
in>>n>>m>>startpoint;
value();
dijkstra();
for(int i=;i<=n;i++)
out<<startpoint<<"-->"<<i<<" "<<dis[i]<<endl;
return ;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iomanip>
#include <vector>
using namespace std;
#define in cin
#define out cout
typedef long long insert;
const int N=2e5+;
const int INF=0x3f3f3f3f;
insert startpoint,n,m,x,y,z,dis[N];
bool vis[N];
struct Node
{
insert to,w;
};
vector<struct Node> vt[N];
void inital_value()
{
for(int i=;i<=m;i++)
{
in>>x>>y>>z;
struct Node now;
now.to=y;now.w=z;
vt[x].push_back(now);
}
memset(dis,INF,sizeof(dis));
dis[startpoint]=;
return;
}
void dijkstra()
{
for(int k=;k<=n;k++)
{
insert minn=INF,pos;
for(int i=;i<=n;i++)
{
if(!vis[i]&&dis[i]<minn)
minn=dis[i],pos=i;
}
vis[pos]=true;
for(int i=;i<vt[pos].size();i++)
{
if(!vis[vt[pos][i].to]&&dis[vt[pos][i].to]>dis[pos]+vt[pos][i].w)
dis[vt[pos][i].to]=dis[pos]+vt[pos][i].w;
}
}
return;
}
int main()
{
in>>n>>m>>startpoint;
inital_value();
dijkstra();
for(int i=;i<=n;i++)
out<<startpoint<<"-->"<<i<<" "<<dis[i]<<" "<<endl;
return ;
}

Dijkstra标准模板的更多相关文章

  1. STL标准模板库(简介)

    标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...

  2. 【转】C++标准库和标准模板库

    C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标准头文件中定义.在C++开发中,要尽可能地利用标准库完成.这样做的直接好处包括:(1)成本:已经作为标准提供,何苦再花费 ...

  3. STL标准模板库介绍

    1. STL介绍 标准模板库STL是当今每个从事C++编程的人需要掌握的技术,所有很有必要总结下 本文将介绍STL并探讨它的三个主要概念:容器.迭代器.算法. STL的最大特点就是: 数据结构和算法的 ...

  4. 【c++】标准模板库STL入门简介与常见用法

    一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部 ...

  5. C++之路起航——标准模板库(vector)

    vector(动态数组或向量):动态分配内存空间的线性储存结构. 需要包括头文件<vector> 定义: vector<数据类型> 变量名: Eg: vector<int ...

  6. C++——string类和标准模板库

    一.string类 1.构造函数 string实际上是basic_string<char>的一个typedef,同时省略了与内存管理相关的参数.size_type是一个依赖于实现的整型,是 ...

  7. STL 简介,标准模板库

    这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL.  当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话 ...

  8. 标准模板库(STL)学习探究之stack

    标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string

  9. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

随机推荐

  1. requireJs sass侧边栏

    koala 下载 将sass编译为css文件 1 嵌套 2 $变量 3 @mixin 函数名(参数) 4 @include 函数    调用 5 @import "xxx"   引 ...

  2. css的基础用法(上)

    css定义: CSS层叠式样表(Cascading  Style Sheets)是一种用来表现html或xml等文件样式的计算机语言.CSS不仅可以静态的修饰网页,还可以配合各种脚本语言动态地对网页个 ...

  3. Mac iOS 允许从任何来源下载应用并打开

    一个快捷的小知识点,mark! 允许从任何来源下载应用并打开,不用手动去允许,更加简洁! 只需一行命令 sudo spctl --master-disable 1.正常情况下,打开偏好设置,选择安全性 ...

  4. 监控tomcat工具使用

    用LambdaProbe监控Tomcat 简介: Lambda Probe(以前称为Tomcat Probe)是一款实时监控和管理的Apache Tomcat实例的基本工具.Lambda Probe ...

  5. LeetCode 简单 - 路径总和(112)

    给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 sum = 22 ...

  6. github 常用

    1.创建KEY,这个文件生成完了后,要保存好公钥和私钥文件 ssh-keygen -t rsa -C "abc@mail.com" 2.github上添加ssh密钥 3.拷贝公钥信 ...

  7. pyqt 多窗口跳转

    今天在做pyqt5的多页面跳转时遇到问题,一点击button按钮,程序会崩溃.在网上查了下,应该是当窗口A调用窗口B的时候,两个窗口不能是同一类型.我写的时候把A.B同时写成了QWidget.把窗口B ...

  8. kafka概述

    kafka概述 Apache Kafka是一个开源 消息 系统,由Scala写成.是由Apache软件基金会开发的一个开源消息系统项目. Kafka最初是由LinkedIn开发,并于2011年初开源. ...

  9. stata操作

    //stata操作 *************************数据基本操作****************************** gen varname = value //定义变量 r ...

  10. 毕业2年 Summary

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/135 看了下去年写毕业一周年总结的时间:2017-6-16,今天 ...