最短路径算法

杭电1874畅通工程续 -最短路径

心已入冬 提交于 2020-01-20 06:48:54
地址: http://acm.hdu.edu.cn/status.php?user=Honor&pid=1874&status=5 题目: Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。 Input 本题目包含多组数据,请处理到文件结束。 每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。 接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。 再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。 Output 对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1. Sample Input 3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2 Sample Output 2 -1 思路:   flyod算法:从a到b的距离等于min(ab,ac+cb);引入中间点c;

图论四:最短路径算法

爷,独闯天下 提交于 2020-01-19 15:25:55
一、广度优先搜索 1、思路:距离开始点最近的点首先被赋值,最远的点最后被赋值。 2、适用范围:对于非负数权的无圈图来说(单源最短路径)。 3、算法实现: (1)一个队列记录每个每个节点的编号。 (2)将起始节点入队,将所有节点到起始节点的距离设置为无穷大,起始节点到起始节点的距离为0; (3)取队列的第一个节点,这个节点出队,遍历这个节点相邻的节点,如果这个节点的距离是INF就变为它前一个节点的距离+1,并且入队。 (4)重复(3)操作,直到所有所有队列为空为止,此时dis数组记录了每一个节点到起始节点的最小距离。 4、代码: #include<iostream> #include<cstdio> #include<queue> #include<vector> using namespace std; const int maxn = 1200; const int INF = 0x3fff; vector <int> vc[maxn]; int dis[maxn]; void bfs(int n) { int i,j,tmp; for(i=1;i<=n;i++) dis[i]=INF; dis[1]=0; queue <int> q; q.push(1); while(!q.empty()) { tmp=q.front(); q.pop(); for(i=0;i<vc[tmp]

图的最短路径

混江龙づ霸主 提交于 2020-01-15 04:26:29
图的最短路径 两种: Dijkstra求单源最短路 Floyd算法求任意两点的最短路 Dijkstra # include <iostream> # include <cstring> # include <cstdio> # include <algorithm> # include <queue> using namespace std ; const int maxn = 1010 ; const int inf = 0x3f3f3f ; int dist [ maxn ] [ maxn ] ; int d [ maxn ] ; int vis [ maxn ] ; int n , m , st , en ; int path [ maxn ] ; void white ( int x ) { if ( path [ x ] == 0 ) { cout << "v" << st << " " ; return ; } white ( path [ x ] ) ; cout << "v" << path [ x ] << " " ; } int main ( ) { while ( scanf ( "%d%d" , & n , & m ) != EOF ) { scanf ( "%d%d" , & st , & en ) ; memset ( dist , inf ,

分支限界法求图的最短路径

北战南征 提交于 2020-01-13 07:29:49
分支限界法 定义: 分支定界 (branch and bound) 算法是一种在问题的解空间树上搜索问题的解的方法。但与回溯算法不同,分支定界算法采用广度优先或最小耗费优先的方法搜索解空间树,并且,在分支定界算法中,每一个活结点只有一次机会成为扩展结点。利用分支定界算法对问题的解空间树进行搜索,它的搜索策略是:   1 .产生当前扩展结点的所有孩子结点;   2 .在产生的孩子结点中,抛弃那些不可能产生可行解(或最优解)的结点;   3 .将其余的孩子结点加入活结点表;   4 .从活结点表中选择下一个活结点作为新的扩展结点。 如此循环,直到找到问题的可行解(最优解)或活结点表为空。分支限界法的思想是:首先确定目标值的上下界,边搜索边减掉搜索树的某些支,提高搜索效率。 问题描述: 给定n个城市,有一个旅行商从某一城市出发,访问每个城市各一次后再回到原出发城市,要求找出的巡回路径最短。 问题分析: 分支限界法是在生成当前E-结点全部儿子之后再生成其它活结点的儿子,且用限界函数帮助避免生成不包含答案结点子树的状态空间的检索方法。在总的原则下,根据对状态控件树中结点检索的次序的不同又将分支限界设计策路分为数种不同的检索方法。在求解旅行商问题时,程序中采用FIFO检索(First In First Out),它的活结点表采用一张先进先出表(即队列)。可以看出

算法分类合集

二次信任 提交于 2020-01-06 08:18:08
算法分类合集 ACM 所有 算法 数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平衡二叉树 二叉排序树 线段树 一维线段树 二维线段树 树状数组 一维树状数组 N维树状数组 字典树 后缀数组,后缀树 块状链表 哈夫曼树 桶,跳跃表 Trie树(静态建树、动态建树) AC自动机 LCA和RMQ问题 KMP算法 图论 基本图算法图 广度优先遍历 深度优先遍历 拓扑排序 割边割点 强连通分量 Tarjan算法 双连通分量 强连通分支及其缩点 图的割边和割点 最小割模型、网络流规约 2-SAT问题 欧拉回路 哈密顿回路 最小生成树 Prim算法 Kruskal算法(稀疏图) Sollin算法 次小生成树 第k小生成树 最优比例生成树 最小树形图 最小度限制生成树 平面点的欧几里德最小生成树 平面点的曼哈顿最小生成树 最小平衡生成树 最短路径 有向无环图的最短路径->拓扑排序 非负权值加权图的最短路径->Dijkstra算法(可使用二叉堆优化) 含负权值加权图的最短路径->Bellmanford算法 含负权值加权图的最短路径->Spfa算法 (稠密带负权图中SPFA的效率并不如Bellman-Ford高) 全源最短路弗洛伊德算法Floyd 全源最短路Johnson算法 次短路径

【图】Dijstra算法

こ雲淡風輕ζ 提交于 2019-12-13 22:08:23
Dijkstra 算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。 代码实现: //Dijkstra bool S[maxsize];//顶点集 int D[maxsize];//到各个顶点的最短路径 int P[maxsize];//记录前驱 void Dijkstra(Graph G,int v){ //初始化 int n=G.vexnum; for(int i=0;i<n;i++){ S[i]=false; D[i]=G.Edge[v][i]; if(D[i]<InF) P[i]=v; else P[i]=-1; } S[v]=true;D[i]=0; //求出最短路径,并入S集 for(int i=1;i<n;i++){ int k,min=INF; for(int j=0;j<n;j++){ if(!S[j]&&D[j]<min){//当前节点未加入S集合且为当前路径最短 min=D[j]; k=j; } } S[k]=true; //更新从源点出发至其余点的最短路径 通过K点 for(int j=0;j<n;j++){ if(!S[j]&&D[k]+G.Edge[k][j]<D[j]){ D[j]=D[k]+G.Edge[k][j]<D[j]; P[j]=k; } } } } 来源: CSDN

Dijkstra和Floyd求最短路径

拥有回忆 提交于 2019-12-10 06:38:25
记录一下这两个算法 Dijkstra # include <stdlib.h> # include <stdio.h> # include <iostream> using namespace std ; /*邻接矩阵法*/ # define MAXV 50 # define INF 32767 typedef struct { int edges [ MAXV ] [ MAXV ] ; int n , e ; } MatGraph ; void CreateGraph ( MatGraph & G ) //创建的是带权有向图 { int n , e ; int x , y , w ; printf ( "输入顶点和边的个数:\n" ) ; cin >> n >> e ; G . e = e ; G . n = n ; for ( int i = 0 ; i < G . n ; i ++ ) for ( int j = 0 ; j < G . n ; j ++ ) { if ( i == j ) G . edges [ i ] [ j ] = 0 ; else G . edges [ i ] [ j ] = INF ; } for ( int i = 0 ; i < G . e ; i ++ ) { printf ( "输入第%d条边的信息\n" , i + 1 ) ; cin >

单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)

元气小坏坏 提交于 2019-12-05 17:50:21
一、基于邻接表的Dijkstra算法   如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点。使用邻接表表示,可以使用 BFS 在O(V + E)时间中遍历图的所有顶点 。这个想法是使用 BFS 遍历图的所有顶点,并使用最小堆存储尚未包括在最短路径树中的顶点(或尚未确定最短距离的顶点)。最小堆用作优先级队列,以从尚未包括的顶点集中获取最小距离顶点。对于Min Heap,诸如 extract-min 和 reduce-key 值之类的操作的时间复杂度为 O(logV)。使用邻接表表示的 Dijkstra算法时间复杂度为 O(ELogV)。 二、详细步骤   1) 创建大小为 V 的最小堆,其中 V 是给定图中的顶点数。 最小堆的每个节点都包含 顶点数 和 顶点的距离值 。   2) 以源顶点为根初始化 Min Heap(分配给源顶点的距离值为 0)。 分配给所有其他顶点的距离值为 INF(无穷大)。   3) 当“最小堆”不为空时,执行以下操作: 从“最小堆”中提取具有最小距离值节点的顶点。让提取的顶点为u。 对于u的每个相邻顶点v,检查v是否在Min Heap中。如果 v 在“最小堆”中,并且距离值大于uv 的权重加上 u 的距离值,则更新 v 的距离值。    用下面的例子来理解。 让给定的源顶点为 0