Dijkstra标准模板
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标准模板的更多相关文章
- STL标准模板库(简介)
标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...
- 【转】C++标准库和标准模板库
C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标准头文件中定义.在C++开发中,要尽可能地利用标准库完成.这样做的直接好处包括:(1)成本:已经作为标准提供,何苦再花费 ...
- STL标准模板库介绍
1. STL介绍 标准模板库STL是当今每个从事C++编程的人需要掌握的技术,所有很有必要总结下 本文将介绍STL并探讨它的三个主要概念:容器.迭代器.算法. STL的最大特点就是: 数据结构和算法的 ...
- 【c++】标准模板库STL入门简介与常见用法
一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部 ...
- C++之路起航——标准模板库(vector)
vector(动态数组或向量):动态分配内存空间的线性储存结构. 需要包括头文件<vector> 定义: vector<数据类型> 变量名: Eg: vector<int ...
- C++——string类和标准模板库
一.string类 1.构造函数 string实际上是basic_string<char>的一个typedef,同时省略了与内存管理相关的参数.size_type是一个依赖于实现的整型,是 ...
- STL 简介,标准模板库
这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL. 当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话 ...
- 标准模板库(STL)学习探究之stack
标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string
- 标准模板库(STL)学习探究之vector容器
标准模板库(STL)学习探究之vector容器 C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...
随机推荐
- Could..... not preload global game manager
发布PC版后出现这个错误,是没有破解成功,卸载后重新安装破解就可以了 http://www.cocoachina.com/bbs/read.php?tid=84587
- spring(三)-事务管理
1. Spring事务管理 事务管理:本质是使用spring管理事务,完成数据库对于事务的支持. 事务:一系列对数据库操作的集合,一个操作错误,所有都必须回滚,其特点是acid. (1)事务并发存在问 ...
- linux 中$ 意思
grep -n sh$ text.txt 查找文件内容中以 Sh 结尾. grep -n ^a text.txt 文件文件内容中以 a 开头. grep -n ^$ text.txt ...
- iOS | Swift图片剪切圆角
我们在IOS开发中,时常需要将一些原本是方形的图片剪切成圆形或者边框是曲线的样子,表现得活泼生动一些. 注意:因为最近在尝试用Swiftl开发,所以这里的语言使用的就是Swift,OC的语法也是相近的 ...
- 获取APP地图权限
获取APP地图权限 NSLocationWhenUseUsageDescription,在info里面设置为空
- c# 获取网络流量
public class ip_helper{enum Constants {MAX_INTERFACE_NAME_LEN=256, MAXLEN_PHYSADDR=8,MAXLEN_IFDESCR= ...
- Debug实验学习汇编
R命令查看.改变CPU寄存器的内容: D命令查看内存中的内容: E命令改写内存中的内容: U命令将内存中的机器指令翻译成汇编指令: T命令执行一条机器指令: A命令以汇编指令的格式在内存中写入一条机器 ...
- js,setTimeout与setInterval的用法
1.setTimeout与setInterval的区别 setTimeout: 1.直接使用的话,按照指定 的时间,只执行一次传入的函数参数. 2.函数的终止使用clearTimeout. setIn ...
- C调用约定__cdecl、__stdcall、__fastcall、__pascal分析
参考原文地址:https://www.cnblogs.com/yenyuloong/p/9626658.html C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们 ...
- ABAP CDS ON HANA-(8)算術式
Arithmetic expression in CDS View Allowed Arithmetic operators in CDS view. CDS View- @AbapCatalog.s ...