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. Spring实现Ioc的多种方式--控制反转、依赖注入、xml配置的方式实现IoC、对象作用域

    Spring实现Ioc的多种方式 一.IoC基础 1.1.概念: 1.IoC 控制反转(Inversion of Control) IoC是一种设计思想. 2.DI 依赖注入 依赖注入是实现IoC的一 ...

  2. Centos7部署kubernetes集群CA证书创建和分发(二)

    1.解压软件包 [root@linux-node1 ~]# cd /usr/local/src/ [root@linux-node1 src]# ls k8s-v1.10.1-manual.zip [ ...

  3. 很Low的三级菜单程序

    # -*-coding:utf-8-*- # Author:sunhao province={ '广东省':{ '深圳市':['南山区','龙岗区','福田区'], '广州市':['荔湾区','海珠区 ...

  4. cc、gcc、g++、CC的区别概括

    gcc是C编译器:g++是C++编译器:linux下cc一般是一个符号连接,指向gcc:gcc和g++都是GUN(组织)的编译器.而CC则一般是makefile里面的一个名字,即宏定义,嘿,因为Lin ...

  5. php多进程和多线程的比较

    前言 最近在学习php多进程和多线程的编程.说实话,这两样在工作中几乎都没有用到,毕竟php并不以异步处理擅长,对于网络请求同步处理可以解决绝大多数问题.但是既然有这样的机制,也了解一下,对于以后接触 ...

  6. wx小程序入门&坑

    1.腾讯云的nodejs版服务代码,在本地用吹cnpm install安装依赖之后,初始化数据库不成功: 换成npm install 并 npm run initdb 之后 可以了.... 2.屏蔽页 ...

  7. Centos7修改profile文件后导致vi command not find

    Centos7修改profile文件后导致vi command not find,原因是profile文件没有配置正确,系统就无法找到精确命令了.解决方法: 1.在命令行中输入:export PATH ...

  8. 【Python】进程3

    #练习: import time from multiprocessing import Pool def run(fn): #fn: 函数参数是数据列表的一个元素 time.sleep(1) ret ...

  9. NEO VM原理及其实现(转载)

    NEO Vm原理及其实现 简介及与evm主要区别 neo vm和evm类似.底层都实现了一套opcode以及对应的执行器,opcode设计差距蛮大的,总体上来说evm的更加简洁,neo vm的功能更加 ...

  10. JAVA小程序-----买衣服

    import java.util.Scanner; //引用扫描器 public class TestDemo1 { public static void main(String [] args){ ...