dijkstra算法

  求某一顶点到其它各个顶点的最短路径;已知某一顶点v0,求它顶点到其它顶点的最短路径,该算法按照最短路径递增的顺序产生一点到其余各顶点的所有最短路径。

对于图G={V,{E}};将图中的顶点分为两组:

  第一组S:求出已知顶点的最短路径的集合

  第二组V-S:尚未求出最短路径的顶点集合(开始为V-{v0}的全部顶点)

该算法将最短路径以递增顺序逐个将第二组顶点加入到第一组顶点中,直到所有的顶点都被加入到第一组顶点集S为止。

dijkstra算法和最小生树中的prim算法类似,都是把顶点看做集合,向所求集合中加点

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; const int INF=0x3f3f;
class Graph
{
private:
int num;
int e;
vector<vector<int> > arr;//存储图的邻接矩阵
vector<bool> visit;//标记该结点是否用过
vector<int> path;//从v0到其他结点的最短路径
public:
Graph();
void dijkstra(const int &i);
};
Graph::Graph()
{
cout<<" num"<<endl;
cin>>num;
cout<<" e"<<endl;
cin>>e; visit.resize(num,false);
path.resize(num); arr.resize(num);
for(int i=;i<num;++i)
arr.at(i).resize(num,INF); cout<<" 边的起始点和终点&&权值"<<endl;
pair<int,int> p;
for(int i=;i<e;++i)
{
cin>>p.first>>p.second;
cin>>arr.at(p.first-).at(p.second-);
}
}
void Graph::dijkstra(const int &index)
{
//首先存储的是index结点到其他节点的最短路径的值
for(int i=;i<num;++i)
path.at(i)=arr.at(index-).at(i);
//初始化visit
visit.at(index-)=true; for(int check=;check<num-;++check)
{
int Min=INF,flag=;
for(int i=;i<num;++i)
{
if(!visit.at(i)&&path.at(i)<Min)
{
flag=i;
Min=path.at(i);
}
}
visit.at(flag)=true;
for(int i=;i<num;++i)//如果由于v0结点的加入导致index结点到其它接点的值变小更新path
{
if(path.at(i)>path.at(flag)+arr.at(flag).at(i))
path.at(i)=path.at(flag)+arr.at(flag).at(i);
}
}
for(int i=;i<num;++i)
cout<<path.at(i)<<"\t";
cout<<endl;
}
int main()
{
Graph g;
g.dijkstra();
return ;
}

floyd算法

  如果要让任意两点(例如从顶点a点到顶点b)之间的路程变短,只能引入第三个点(顶点k),并通过这个顶点k中转即a->k->b,才可能缩短原来从顶点a点到顶点b的路程。那么这个中转的顶点k是1~n中的哪个点呢?甚至有时候不只通过一个点,而是经过两个点或者更多点中转会更短。

  当任意两点之间不允许经过第三个点时,这些城市之间最短路程就是初始路程

  一:假如现在只允许经过1号顶点,求任意两点之间的最短路程,只需判断e[i][1]+e[1][j]是否比e[i][j]要小即可。e[i][j]表示的是从i号顶点到j号顶点之间的路程。e[i][1]+e[1][j]表示的是从i号顶点先到1号顶点,再从1号顶点到j号顶点的路程之和。其中i是1~n循环,j也是1~n循环

for (i = ; i <= n; i++)
for (j = ; j <= n; j++)
{
if (e[i][j] > e[i][] + e[][j])
e[i][j] = e[i][] + e[][j];
}

  在只允许经过1号顶点的情况下,任意两点之间的最短路程更新为

  二:接下来继续求在只允许经过1和2号两个顶点的情况下任意两点之间的最短路程,我们需要在只允许经过1号顶点时任意两点的最短路程的结果下,再判断如果经过2号顶点是否可以使得i号顶点到j号顶点之间的路程变得更短。即判断e[i][2]+e[2][j]是否比e[i][j]要小,

//经过1号顶点
for(i=;i<=n;i++)
for(j=;j<=n;j++)
if (e[i][j]>e[i][]+e[][j])
e[i][j]=e[i][]+e[][j]; //经过2号顶点
for(i=;i<=n;i++)
for(j=;j<=n;j++)
if(e[i][j] > e[i][]+e[][j])
e[i][j]=e[i][]+e[][j];

  在只允许经过1和2号顶点的情况下,任意两点之间的最短路程更新为:

  三:最后允许通过所有顶点作为中转

  最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。用一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。

for(k=;k<=n;k++)//允许中转的k个结点
for(i=;i<=n;i++)//源地点i
for(j=;j<=n;j++)//目标地点j
if(e[i][j]>e[i][k]+e[k][j])
e[i][j]=e[i][k]+e[k][j];

code:求固定两地点的最短路径

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; const int INF=0x3f3f;
class Graph
{
private:
int num;
int e;
vector<vector<int> > arr;//存储图的邻接矩阵
vector<int> path;//从v0到其他结点的最短路径
public:
Graph();
void floyd(const int &begin,const int &end);
};
Graph::Graph()
{
cout<<" num"<<endl;
cin>>num;
cout<<" e"<<endl;
cin>>e; path.resize(num); arr.resize(num);
for(int i=;i<num;++i)
arr.at(i).resize(num,INF); cout<<" 边的起始点和终点&&权值"<<endl;
pair<int,int> p;
for(int i=;i<e;++i)
{
cin>>p.first>>p.second;
cin>>arr.at(p.first-).at(p.second-);
}
}
void Graph::floyd(const int &begin,const int &end)
{
//允许经过的中转点;k==0,经过第一个中转点,==1经过第二个中转点(此时已经进过两个中转点
//最多可以经过n个中转点)
for(int k=;k<num;++k)
if(arr.at(begin-).at(end-)>arr.at(begin-).at(k)+arr.at(k).at(end-))
arr.at(begin-).at(end-)=arr.at(begin-).at(k)+arr.at(k).at(end-); cout<<arr.at(begin-).at(end-)<<endl;
}
int main()
{
Graph g;
g.floyd(,);
return ;
}

图的最短路径——dijkstra算法和Floyd算法的更多相关文章

  1. 最短路径——Dijkstra算法和Floyd算法

    Dijkstra算法概述 Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图(无 ...

  2. 最短路径Dijkstra算法和Floyd算法整理、

    转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijks ...

  3. 【转】最短路径——Dijkstra算法和Floyd算法

    [转]最短路径--Dijkstra算法和Floyd算法 标签(空格分隔): 算法 本文是转载,原文在:最短路径-Dijkstra算法和Floyd算法 注意:以下代码 只是描述思路,没有测试过!! Di ...

  4. 最短路径—Dijkstra算法和Floyd算法

    原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最后边附有我根据文中Dijkstra算法的描述使用jav ...

  5. 最短路径—Dijkstra算法和Floyd算法【转】

    本文来自博客园的文章:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html Dijkstra算法 1.定义概览 Dijk ...

  6. 【转载】最短路径—Dijkstra算法和Floyd算法

    注意:以下代码 只是描述思路,没有测试过!! Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始 ...

  7. 最短路径—Dijkstra 算法和Floyd 算法

    某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在 ...

  8. 【转载】Dijkstra算法和Floyd算法的正确性证明

      说明: 本文仅提供关于两个算法的正确性的证明,不涉及对算法的过程描述和实现细节 本人算法菜鸟一枚,提供的证明仅是自己的思路,不保证正确,仅供参考,若有错误,欢迎拍砖指正   ----------- ...

  9. Dijkstra算法和Floyd算法的正确性证明

    说明: 本文仅提供关于两个算法的正确性的证明,不涉及对算法的过程描述和实现细节 本人算法菜鸟一枚,提供的证明仅是自己的思路,不保证正确,仅供参考,若有错误,欢迎拍砖指正   ------------- ...

随机推荐

  1. ajax返回数据定义为全局变量

    var result;   //定义全局变量    $(document).ready(function(){          $.ajax({                   type:'PO ...

  2. OJ_查找二叉树

    #include<iostream>using namespace std;int n,m;int d[120];int t=1;int re;struct Node{ int data; ...

  3. 【重大更新】DevExpress WinForms v18.2新版亮点(七)

    买 DevExpress Universal Subscription  免费赠 万元汉化资源包1套! 限量15套!先到先得,送完即止!立即抢购>> 行业领先的.NET界面控件2018年第 ...

  4. <zk的典型应用场景>

    Overview zk是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布与订阅. 另一方面,通过对zk中丰富的数据节点进行交叉使用,配合watcher事件通 ...

  5. phpstom pojie

    https://blog.csdn.net/gu_wen_jie/article/details/79136475

  6. 2019-03-08-day007-深浅拷贝

    01 昨日内容回顾 is 两者之间的id是否相同 == 两边的数值是否相等 id 获取该对象的内存地址 代码块: 一个文件,交互式命令行:一行是个一个代码块. 同一代码块下: 字符串的缓存机制,驻留机 ...

  7. three probing way of openadress hash

  8. 怪异盒模型和标准盒模型--CSS

    一,原理 css 属性:Box Moel分为两种:W3C标准和IE标准盒子模型. 大多数浏览器采用W3C标准模型,而IE中采用Microsoft自己的标准. 怪异模式是“部分浏览器在支持W3C标准的同 ...

  9. 2.22 JS处理富文本

    2.22 JS处理富文本 前言    <富文本>这篇解决了富文本上iframe问题,其实没什么特别之处,主要是iframe的切换,本篇讲解通过js的方法处理富文本上iframe的问题一.加 ...

  10. websocket js 代码样例

    function StartWebSocket(wsUri) { websocket = new WebSocket(wsUri); websocket.onopen = function(evt) ...