问题描述

求无负权图中点s到点t的最短凝聚力

备注

标准说法中,“缩短”/“松弛”(relax)操作是对边进行的。下面为了行文方便,将其拓展到点。即以下操作,其中A表示目前已经算出的点i到j的距离:

A[i][j]=min(A[i][v] + A[v][j] , A[i][j]) (同时维护path数组)

算法思路

类似于按拓扑排序的顺序,对所有点进行缩短操作。

下面具体阐述。

用d[i]记录已算出的点s到点j之间的距离,path[j]记录目前算出的s到j最短路径中,j节点的上一个节点

将点分为两个集合:已完成的Known和未完成的unknown.

初始时,将所有d赋为无穷大,d[s]赋为0;所有点均为unknown

循环:对unknown的所有点,择其d最小者,进行缩短操作,该点加入known。直到所有点都为known。

实现思路

用一个数组known,known[i]为1则表示known,为0 表示unknown

一些恼人的小问题

1.无穷大问题

假设输入的邻接矩阵中,每点与自己的权值为0,不邻接的两点权值为MAX,MAX被宏定义为一个非常大但不容易溢出的整数。

2.多维动态数组传参问题

受编译器原理的限制,C/C++将多维动态数组作为函数参数传递是非常麻烦的,比如邻接矩阵。

源码

#include<iostream>
using namespace std; #define MAX 50000 void printPath(int path[], int n,int s,int t)
{
if (t == s)
cout << s;
else
{
printPath(path, n, s, path[t]);
cout << "->"<<t;
} }
/*
仅适用于无负权的图
distance是目前算出的s到某点的距离数组,path是从s到某点v的最短路径中,v的上一节点
初始化将distance全部赋为正无穷,之后从s点开始,进行缩短操作,
此后选择未进行缩短的点中distance最小者进行缩短,直至所有点都完成了缩短操作
*/
int main()
{
/*-----------------------声明与定义--------------------*/
int n =7, s = 0, t = 0, i, distS2T;
int G[7][7] =
{ 0,4,5,6,MAX,MAX,MAX,
4,0,3,MAX,1,MAX,MAX,
5,3,0,MAX,MAX,2,MAX,
6,MAX,MAX,0,2,MAX,MAX,
MAX,1,MAX,2,0,MAX,4,
MAX,MAX,2,MAX,MAX,0,3,
MAX,MAX,MAX,MAX,4,3,0
};
int *known = new int[n](), *distance = new int[n],*path = new int[n]; //如果s到某点距离已经确定了(该点已经被用于relax过了),则known为1,否则为0
//disFromS[]数组是s到各点的最短距离.
//---------------------------------赋初值-------------------------------
for (i = 0; i < n; i++)
{
distance[i] = MAX;
}
distance[s] = 0;
path[s] = s; //------循环:选择unknown的点中dis最小的进行缩短操作,直到所有点全部为known------ while (1) //there's stil unknown vertex
{ i = 0;
while (known[i] == 1 && i<n)
i++;//find the first unknown vertex
if (i >= n) break; //if all vertices are known ,end the algorithm
int v = i;
for (; i < n; i++) //find the unknown vertex with the min distance
{
if (!known[i] && distance[v] > distance[i]) v = i;
} //relax(minPos); modify dis and parent
for (i = 0; i < n; i++)
{
//for each unknown vertex i,
if (known[i]) continue;
if (distance[i] > distance[v] + G[v][i])
{
distance[i] = distance[v] + G[v][i];
path[i] = v;
}
}
known[v] = 1;
} //--------------输出&释放内存----------------------
distS2T = distance[t];
cout << distS2T<<endl;
for (i = 0; i < n;i++)
cout << path[i] << " ";
cout << endl;
for (i = 0; i < n; i++)
cout << distance[i]<<" ";
cout << endl;
printPath(path, n, 0, 6); delete[] known;
delete[] distance;
delete[] path;
while (1);
return 0; }

Dijkstra算法C++实现总结的更多相关文章

  1. 求两点之间最短路径-Dijkstra算法

     Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...

  2. Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解

    /* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...

  3. 关于dijkstra算法的一点理解

    最近在准备ccf,各种补算法,图的算法基本差不多看了一遍.今天看的是Dijkstra算法,这个算法有点难理解,如果不深入想的话想要搞明白还是不容易的.弄了一个晚自习,先看书大致明白了原理,就根据书上的 ...

  4. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  5. Dijkstra算法(二)之 C++详解

    本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...

  6. Dijkstra算法(一)之 C语言详解

    本章介绍迪杰斯特拉算法.和以往一样,本文会先对迪杰斯特拉算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法 ...

  7. 最短路问题Dijkstra算法

    Dijkstra算法可以解决源点到任意点的最短距离并输出最短路径 准备: 建立一个距离数组d[ n ],记录每个点到源点的距离是多少 建立一个访问数组v[ n ],记录每个点是否被访问到 建立一个祖先 ...

  8. dijkstra算法求最短路

    艾兹格·W·迪科斯彻 (Edsger Wybe Dijkstra,1930年5月11日~2002年8月6日)荷兰人. 计算机科学家,毕业就职于荷兰Leiden大学,早年钻研物理及数学,而后转为计算学. ...

  9. 数据结构之Dijkstra算法

    基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求 ...

  10. ACM: HDU 1869 六度分离-Dijkstra算法

    HDU 1869六度分离 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descri ...

随机推荐

  1. 【数据结构(C语言版)系列二】 栈

    栈和队列是两种重要的线性结构.从数据结构角度看,栈和队列也是线性表,但它们是操作受限的线性表,因此,可称为限定性的数据结构.但从数据类型角度看,它们是和线性表大不相同的两类重要的抽象数据类型. 栈的定 ...

  2. 洛谷 P3332 [ZJOI2013]K大数查询 || bzoj3110

    用树套树就很麻烦,用整体二分就成了裸题.... 错误: 1.尝试线段树套平衡树,码农,而且n*log^3(n)慢慢卡反正我觉得卡不过去 2.线段树pushdown写错...加法tag对于区间和的更新应 ...

  3. Oracle Mysql的jdbc连接

    Oracle和MySql的jdbc或连接池中的连接,写下来以便随时参考 Oracle: driverClassName=oracle.jdbc.driver.OracleDriver url=jdbc ...

  4. 【JavaScript】随机生成10个0~100的数字

    随机生成10个0~100不重复的数字(包含0和100): 需要用到的知识点:随机数 去重 下面放代码 <!DOCTYPE html> <html> <head> & ...

  5. Android 使用Bitmap将自身保存为文件,BitmapFactory从File中解析图片并防止OOM

    1.使用Bitmap将自身保存为文件 public boolean saveBitmapAsFile(String name, Bitmap bitmap) { File saveFile = new ...

  6. SceneAction$$FastClassByCGLIB$$7330f7b9.invoke(int, Object, Object[]) line: not available

    现象:在调试状态下,断点可以进入ACTION ,当调用service的时候,发现无法进入service中的断点,就报了题目中的错误. 过程:1.降低JDK.因为本工程是用JDK1.6编译的,maven ...

  7. RGB、YUV和YCbCr介绍【转】

    RGB: 就是常说的红(Red).绿(Green)和蓝(Blue),每个图像的像素点由RGB三个通道的值组成. YUV和YCbCr: YUV与RGB的转换: Y'= 0.299*R' + 0.587* ...

  8. Node.js——post方式提交的图片如何保存

    https://www.cnblogs.com/bruce-gou/p/6399766.html 没有使用express框架,主要是对于 request 的监听,data的时候对数据进行保存,end的 ...

  9. [Windows Server 2008] 阿里云.云主机忘记密码解决方法

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:解决阿里云 ...

  10. 【分享】iTOP-iMX6UL开发板驱动看门狗 watchdog 以及 Linux-c 测试例程

    iTOP-iMX6UL开发板看门狗测试例程,iTOP-iMX6UL 开发板的看门狗驱动默认已经配置,可以直接使用测试例程. 版本 V1.1:1.格式修改:2.例程修改完善,其中增加喂狗代码.1 看门狗 ...