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之所以被 ...
随机推荐
- 【luogu P1514 引水入城】 题解
题目链接:https://www.luogu.org/problemnew/show/P1514 // luogu-judger-enable-o2 #include <iostream> ...
- JQuery 禁用后退按钮
jQuery(document).ready(function () { if (window.history && window.history.pushState) { $(win ...
- webpack4——打包html报错解决
①先引入html-webpack-plugin插件,然后在终端下载 npm install --save-dev html-webpack-plugin ②我的文件结构 ③修改webpack.dev. ...
- vue项目模拟后台数据
这次我们来模拟一些后台数据,然后去请求它并且将其渲染到界面上.关于项目的搭建鄙人斗胆向大家推荐我的一篇随笔<Vue开发环境搭建及热更新> 一.数据建立 我这里为了演示这个过程所以自己编写了 ...
- 2018-03-21 11:34:44 java脚本批量转换java utf-8 bom源码文件为utf-8编码文件
package com.springbootdubbo; import java.io.*;import java.util.ArrayList;import java.util.List; /** ...
- c#数据库连接池Hikari重构升级
Hikari是我自定义的数据库连接池,前面已经提供了地址.因为c#的连接池按照规范的ADO.NET里面实现定义的.由数据库官方提供,但是实现方式就不知道了,反正没有看出来,估计一般是连接类实现的,但是 ...
- windows 开启 nginx 监听80 端口 以及 禁用 http 服务后,无法重启 HTTP 服务,提示 系统错误 123,文件目录、卷标出错
1. 正常情况直接运行 start nginx.exe 不能开启成功,因为 80 端口被占用.提示: bind() to 0.0.0.0:80 failed (10013: An attempt w ...
- 重新格式化hadoop的namenode导致datanode无法启动的最简单解决办法
一般namenode只格式化一次,重新格式化不仅会导致之前的数据都不可用,而且datanode也会无法启动.在datanode日志中会有类似如下的报错信息: java.io.IOException: ...
- HTTP缓存初探
缓存的作用 用户访问一个web页面的频率远高于web页面更新的频率,因此多数时候用户从服务器获取的html.js.css以及图片等内容都是相同的,如果每次访问都从服务器获取这些静态内容即降低了页面加载 ...
- dom4j里面封装方法的操作
animal.xml <?xml version="1.0" encoding="UTF-8"?><animal> <cat ...