1、建图

const int maxNum = 0x3f3f3f3f;  // 定义一个足够大的数,代表图中两顶点间无边
class graph
{
private:int V;
public:vector<vector<int> > g;graph(int V){this->V = V;// g为二维数组,里面每个元素初始化为无穷大g = vector<vector<int> >(V, vector<int>(V, maxNum));}~graph(){};int getV() { return V; }void addEdge(int s, int t, int w);
};
void graph::addEdge(int s, int t, int w) {g[s][t] = w;g[t][s] = w;
}

\quad 图有V个顶点,默认标号为0到V-1。这样,我们就可以通过调用addEdge给图添加从是s点到t点权重为w的一条边。
如果我们要建立如下图所示这样一个图,我们把a点看作0,b点看作7,则建图过程为:

int main()
{graph G(8);G.addEdge(0, 1, 2);G.addEdge(0, 2, 8);G.addEdge(0, 3, 1);G.addEdge(1, 2, 6);G.addEdge(1, 4, 1);G.addEdge(2, 3, 7);G.addEdge(2, 4, 4);G.addEdge(2, 5, 2);G.addEdge(2, 6, 2);G.addEdge(3, 6, 9);G.addEdge(4, 5, 3);G.addEdge(4, 7, 9);G.addEdge(5, 6, 4);G.addEdge(5, 7, 6);G.addEdge(6, 7, 2);return 0;
}

2、初始化和大体框架

\quad我们先来看看初始化和大体框架,最后再来写算法的核心部分。

class Dantjig
{
private:graph &G;int v;  // 起始点bool *visited;  // 判断顶点是否已标号int *t;  // 顶点的标号值,表示初始点到当前点的最短路长度vector<int> A;  // 访问过的顶点集合vector<pair<int, int> > T; // 访问过的边集合,用于输出路劲
public:Dantjig(graph &graph, int v): G(graph){// 初始化各个变量visited = new bool[G.getV()];t = new int[G.getV()];for (int i = 0; i < G.getV(); ++i) {visited[i] = false;t[i] = 0;}this->v = v;A.clear();_Dantjig(v); // 算法核心}~Dantjig(){delete[] visited;delete[] t;A.clear();T.clear();}void _Dantjig(int v);  // 申明算法// 返回v点到w点的最短距离int minLen(int w){return t[w];}// 找出顶点to对应的另一个顶点fromint getfrom(int to){for (int i = 0; i < T.size(); ++i) {if(T[i].second==to) return T[i].first;}}// 打印路径void showpath(int w){stack<int> s;int from = getfrom(w);while(from!=v){s.push(from);from = getfrom(from);}s.push(v);while(!s.empty()){cout << s.top() << "->";s.pop();}cout << w << endl;}
};

\quad在类的成员变量中A是已被标记的点,T是访问过的边的集合。上图中如果以a点为起点,b点为终点输入,运形程序后,T={(0,3)(0,1)(1,4)(4,5)(4,2)(2,6)(6,7)}T=\{(0,3) (0,1) (1,4) (4,5) (4,2) (2,6) (6,7)\}T={(0,3)(0,1)(1,4)(4,5)(4,2)(2,6)(6,7)}。getfrom函数就是找出T中一条边中后面一个点的前一个点。比如要找出7这个点对应的点6,就可以用getfrom得到。showpath即可从终点开始,在T中不断搜索前一个节点,存在栈stack中,之后输出即为起点到终点的路劲。

3、算法核心

void Dantjig::_Dantjig(int v) {A.push_back(v);if(A.size()==G.getV())  // 图中所有顶点均已标记,结束递归return;visited[v] = true;int minWeight = maxNum; // 存储当前结点下相邻节点中拥有的最短的边长度int minV;  // 存放下一个被标记的顶点int from, to;  // 记录路劲for (int i = 0; i < A.size(); ++i) {for (int j = 0; j < G.getV(); ++j) {if(!visited[j] && G.g[A[i]][j]!=maxNum){int temp = t[A[i]];if(temp+G.g[A[i]][j] < minWeight){minWeight = temp+G.g[A[i]][j];minV = j;from = A[i];to = j;}}}}T.push_back(make_pair(from, to));t[minV] = minWeight;  // 更新起始点到该点的最短路劲值_Dantjig(minV);   // 递归调用即可
}

4、所有程序如下:

//
// Created by 程勇 on 2019/3/7.
//#include<bits/stdc++.h>
using namespace std;const int maxNum = 0x3f3f3f3f;  // 定义一个足够大的数,代表图中两顶点间无边
class graph
{
private:int V;
public:vector<vector<int> > g;graph(int V){this->V = V;// g为二维数组,里面每个元素初始化为无穷大g = vector<vector<int> >(V, vector<int>(V, maxNum));}~graph(){};int getV() { return V; }void addEdge(int s, int t, int w);
};void graph::addEdge(int s, int t, int w) {g[s][t] = w;g[t][s] = w;
}class Dantjig
{
private:graph &G;int v;  // 起始点bool *visited;  // 判断顶点是否已标号int *t;  // 顶点的标号值,表示初始点到当前点的最短路长度vector<int> A;  // 访问过的顶点集合vector<pair<int, int> > T; // 访问过的边集合,用于输出路劲
public:Dantjig(graph &graph, int v): G(graph){// 初始化各个变量visited = new bool[G.getV()];t = new int[G.getV()];for (int i = 0; i < G.getV(); ++i) {visited[i] = false;t[i] = 0;}this->v = v;A.clear();_Dantjig(v); // 算法核心}~Dantjig(){delete[] visited;delete[] t;A.clear();T.clear();}void _Dantjig(int v);  // 申明算法// 返回v点到w点的最短距离int minLen(int w){return t[w];}// 找出顶点to对应的另一个顶点fromint getfrom(int to){for (int i = 0; i < T.size(); ++i) {if(T[i].second==to) return T[i].first;}}// 打印路径void showpath(int w){stack<int> s;int from = getfrom(w);while(from!=v){s.push(from);from = getfrom(from);}s.push(v);while(!s.empty()){cout << s.top() << "->";s.pop();}cout << w << endl;}
};void Dantjig::_Dantjig(int v) {A.push_back(v);if(A.size()==G.getV())  // 图中所有顶点均已标记,结束递归return;visited[v] = true;int minWeight = maxNum; // 存储当前结点下相邻节点中拥有的最短的边长度int minV;  // 存放下一个被标记的顶点int from, to;  // 记录路劲for (int i = 0; i < A.size(); ++i) {for (int j = 0; j < G.getV(); ++j) {if(!visited[j] && G.g[A[i]][j]!=maxNum){int temp = t[A[i]];if(temp+G.g[A[i]][j] < minWeight){minWeight = temp+G.g[A[i]][j];minV = j;from = A[i];to = j;}}}}T.push_back(make_pair(from, to));t[minV] = minWeight;  // 更新起始点到该点的最短路劲值_Dantjig(minV);   // 递归调用即可
}int main()
{graph G(8);G.addEdge(0, 1, 2);G.addEdge(0, 2, 8);G.addEdge(0, 3, 1);G.addEdge(1, 2, 6);G.addEdge(1, 4, 1);G.addEdge(2, 3, 7);G.addEdge(2, 4, 4);G.addEdge(2, 5, 2);G.addEdge(2, 6, 2);G.addEdge(3, 6, 9);G.addEdge(4, 5, 3);G.addEdge(4, 7, 9);G.addEdge(5, 6, 4);G.addEdge(5, 7, 6);G.addEdge(6, 7, 2);Dantjig dantjig(G, 0);// 输出a到b(即0到7)的最短距离cout << dantjig.minLen(7) << endl;dantjig.showpath(7); // 打印路径return 0;
}

运行结果如下:

图论(四)最短路算法Dantjig的实现相关推荐

  1. 【阿良的算法之路】图论最短路算法模板

    图论: [阿良的算法之路]图论最短路算法模板 [模板]dirjkstra单源最短路径 [模板]Bellman-Ford多源最短路 [模板]Spfa求最短路 [模板]Spfa判断负环 [模板]Floya ...

  2. 【讲解 + 模板】四种最短路算法的比较

    四种最短路算法的比较 最短路 最短路,顾名思义,最短的路径. 我们把边带有权值的图称为带权图.边的权值可以理解为两点之间的距离.一张图中任意两点之间会有不同的路径相连.最短路径就是指连接两点的这些路径 ...

  3. 超详细!图论最短路算法与极简c++代码(配题目)

    最短路算法知识结构图 /* 最短路问题{单源最短路{1.所有边权都是正数{1.朴素Dijkstra算法 O(n^2) 适用于稠密图2.堆优化的Dijkstra O(mlog(n)) 适用于稀疏图}2. ...

  4. 2019中山纪念中学夏令营-Day14 图论初步【dijkstra算法求最短路】

    Dijkstra是我学会的第一个最短路算法,为什么不先去学SPFA呢?因为我在luogu上翻到了一张比较神奇的图: 关于SPFA -它死了 以及网上还有各位大佬的经验告诉我:SPFA这玩意很容易被卡. ...

  5. floyd最短路算法的matlab程序,图论之最短路01——最短路矩阵(FLOYD)算法

    %======================================================== %最短路矩阵算法,FLOYD算法 %针对性:方案预算,能求出所有点之间的最短路(最小 ...

  6. 图论01.最短路专题_学习笔记+模板

    图论01.最短路专题_学习笔记+模板 一.定义与性质 ● 需要的前导知识点 路径 最短路 有向图中的最短路.无向图中的最短路 单源最短路.每对结点之间的最短路 ● 最短路的性质 对于边权为正的图,任意 ...

  7. 算法小讲堂之最短路算法(Floyd+bellman+SPFA+Dijkstra)

    前言 如果你对图论相关知识一点也没有,那么建议您先去了解这些知识:https://acmer.blog.csdn.net/article/details/122310835,然后就可以快乐的学习最短路 ...

  8. 解题报告:【kuangbin带你飞】专题四 最短路练习题

    目录 A. POJ - 2387 TiltheCowsComeHomeTil\ the\ Cows\ Come\ HomeTil the Cows Come Home--------(最短路模板题)[ ...

  9. 最短路算法总结(入门版)

    最近花了大约一个月左右的时间集中刷了一些图论的题目.虽然收获了许多但是还是付出了很多作业没有做的代价0.0.在这里先把自己所做的关于最短路的基础算法来做一个总结,至少把学到的东西记录下来. 先说明一下 ...

最新文章

  1. 这是入门生信,学习生信分析思路和数据可视化的首选?
  2. Why Did the Cow Cross the Road III(树状数组)
  3. rtmp推流直播流程
  4. SQL30081N 检测到通信错误。正在使用的通信协议:TCP/IP
  5. MySQL如何跨机器迁移数据?
  6. ant design 预览图片_AntD框架的upload组件上传图片时遇到的一些坑
  7. 用rz,sz命令在xshell传输文件
  8. [最后召集:西瓜糖、editasp]微软MVP呕心力作《我的第一本C++书》新鲜出炉,围观即有机会获新书免费送...
  9. oracle拼接空格错误,oracle运维故事 一个空格引发的血案
  10. 中国计算机学会推荐国际学术会议和期刊目录——A、B、C类期刊会议分级信息
  11. 阿里巴巴最新分销模式淘易客分销
  12. CSDN 博客更换皮肤
  13. 接上篇手工课 材料:美女图片一张, 要求将其制成 边旋转边渐隐的魔幻图片
  14. k个一组翻转链表 哔哩哔哩2020校园招聘笔试题/LeetCode_25(困难)讲解
  15. Runes——Dart
  16. Windows 服务器刷题(带答案)
  17. 分享66个NET源码,总有一款适合您
  18. 技术至简-5:动画显示复指数信号的形状与物理意义
  19. 智慧城市66版的没有电子名片功能,如何解决
  20. 基于php农产品在线销售网站

热门文章

  1. 图像显著性检测——时域分析(谱残差法、相位谱法)
  2. 2022级计算机保研历程
  3. 8.8 Web前端-小米商城项目实战
  4. 项目总结3 类似网易云音乐导航栏指示器(个性推荐、歌单等)的简单实现(一)
  5. 微果I7随身便携投影仪好不好用?和哈趣H1相比哪个更值得入手?
  6. RFID射频卡超市购物结算系统
  7. 不成熟的男人的爱情观——知乎上另一个关于不成熟男人的见解
  8. 2022.07.12 第九小组 高小涵 学习笔记
  9. 全网首发!马士兵内部共享—1658页《Java面试突击核心讲》
  10. android工程师培训价格,徐州android工程师培训基地