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. 理解AXI Quad Serial Peripheral Interface(SPI) IP核

    reference :   PG153-AXI Quad SPI v3.2 LogiCORE IP Product Guide.pdf 在使用MicroBlaze过程中,调用了此IP,所以有必须仔细学 ...

  2. 1085 PAT单位排行

    每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜.本题就请你实现这个功能. 输入格式: 输入第一行给出一个正整数 N(≤10​^5​​),即考生人数.随后 N 行,每行按下列格式给出一个考 ...

  3. DevExpress Windows 10 UWP Controls新版亮点

    行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExpress Windows 10 U ...

  4. redis 五大数据类型之list篇

    1.lpush/lpop/rpop/rpush/lrange  这里的list就是链表,lpush就是从左往右插入数据,rpush就是从右往左插数据,lrange就是从左往右范围性的取值,pop就是弹 ...

  5. 2019-02-25 EST 科技文翻译

    The Definition of Theme and Rheme The point of departure is equally presented to the speaker and to ...

  6. Word2Vec实现原理(Hierarchical Softmax)

    由于word2vec有两种改进方法,一种是基于Hierarchical Softmax的,另一种是基于Negative Sampling的.本文关注于基于Hierarchical Softmax的改进 ...

  7. 中文字符utf-8编码原则

    UTF-8是一种变长字节编码方式.对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0:如果是 多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字 ...

  8. Vue数组操作不刷新视图问题的解决

    最近使用Vue2.0开发项目,有一个列表使用v-for绑定到数组,按照Vue的推荐方案,使用push.splice.this.$set三个变异方法操作数组.发现在添加页面,三个方法都能及时刷新视图:但 ...

  9. mybatis Condition查询

    Condition condition = new Condition(ACurrentTotal.class); condition.createCriteria().andCondition(&q ...

  10. 6--Python入门--Python基本运算符

    算数运算符 运算符 描述 示例 + 相加 1+1→2 - 相减 1-1→0 * 相乘 1*2→2 / 相除 1/2→0.5 % 取余数 3%2→1 ** 幂运算 2**2→4 // 取商 7//2→3 ...