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之所以被 ...
随机推荐
- Android学习笔记_62_手机安全卫士知识点归纳(2)ListView重要属性 PopupWindow应用
1.缓存颜色: 为什么ListView在拖动的时间是黑色,而静止时间是自己的颜色是因为 ListView的缓存.只需一个配置即可.在这个ListView里面加上它即可. android:cacheCo ...
- WebApiConfig设置返回json并且对于get,post可以重名
webapi2默认返回的是xml格式的,并且一个控制器中的方法名不能重名,列如:一个get,一个post这个也是不允许的,这些我们都可以进行设置. 下面设置:返回json格式,并且一个控制器中的方法可 ...
- 整理关于 VS Code 一些小技巧:系列一
官方介绍 VisualStudioCode是一个轻量级且功能强大的源代码编辑器,它运行在桌面上,支持Windows.MacOS和Linux系统.它提供了对JavaScript.TypeScript和N ...
- 19.springboot邮件服务服务器部署访问不到邮箱服务器解决方案
1.前言 在Springboot项目的生产环境中,win系统环境下,邮箱服务是可以正常使用的. 当项目部署到阿里云服务器上之后,因为服务器端口采用安全组的方式,25端口访问不到. 在网上查找了一部分资 ...
- java 后台返回文件流到浏览器
package com.springbootblog.controller; import io.swagger.annotations.ApiImplicitParam;import io.swag ...
- ABAP术语-Call Transaction
Call Transaction 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/15/1039270.html A data transfe ...
- Oracle VM VirtualBox 安装XP、Win 7
测试要求 为了少写点lr脚本(其实是不会写),看到fiddler的saz格式文件可以由loadrunner 12读取,本机安装了lr 11,打算虚拟机安装lr 12.通过共享文件夹把文件传过去,生成脚 ...
- .scripts/mysql_install_db: 没有那个文件或目录
.scripts/mysql_install_db: 没有那个文件或目录 查了好多地方,在书上找到了解决方案,太不容易了 原因与解决方法: 系统与MYSQL版本不同,系统64位使用64位MYSQL,3 ...
- java后台去除JSON数组的重复值
假设原始Json数组是这样的 原始JSONArry:[{"Value":"15153129877","Key":"09770985 ...
- 终于搞定了cxgrid的多行表头(转终于搞定了cxgrid的多行表头 )
终于搞定了cxgrid的多行表头 转自:http://mycreature.blog.163.com/blog/static/556317200772524226400/ 这一周都在处理dbg ...