最短路径

经典问题----最短路径(Floyd弗洛伊德算法)(HDU2066)

二次信任 提交于 2020-03-04 07:33:18
问题简介: 给定T条路,S个起点,D个终点,求最短的起点到终点的距离。 思路简介: 弗洛伊德算法即先以a作为中转点,再以a、b作为中转点,直到所有的点都做过中转点,求得所有点到其他点的最短路径,Floyd算法适用于多源最短路径,是一种动态规划算法,稠密图效果最佳,边权可正可负。优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。缺点:时间复杂度比较高,不适合计算大量数据。Floyd算法时间复杂度为n^3,Dijikstra算法为n^2。 优化代码: #include <iostream> #include <cmath> #include <stdio.h> #include <cstdio> #include <cstring> #include<algorithm> #include<time.h> #include<math.h> #include <stdlib.h> #include <string.h> #include <stack> using namespace std; #define MAXN 1000000 #define N 1010 int map[N][N], s[N], e[N], maxx; int T, S, D; int floyd() { int res = MAXN; for (int k = 1; k <= maxx; k+

多种最短路径或生成树问题小计

倖福魔咒の 提交于 2020-03-03 13:18:42
最短路径问题的变种真的是层出不穷,本羸弱已经写了不少了,先写一篇总结,之后慢慢加吧 生成树模板题 最短网络 多源点最短路径优化 一般我们使用Floyd算法计算所有点之间的最短路径,但是复杂度很高,在这道题这里显然是不行的。这时候需要一个小技巧: 反向建图,将多个点到一个点的最短路径转化为单个点到多个点的最短路径。 题解 行走次数有限的最短路径 与普通的最短路径问题不同,这类题的限制在于路径的数目不能超过某个值 n n n ,而且本题还有另一个难点,如何决定在哪条路径上使用哪一个车票。这类题组合数非常之多,一般考虑将限制因素用整数表示为集合, 题解 TSP问题 TSP问题与一般最短路径的问题在于经过每个顶点恰好一次,并且最终回到起点这个约束,对于这个问题,我们一般采用 状态压缩DP 的思想,将经过的点集化为集合,用 d p [ S ] [ v ] dp[S][v] d p [ S ] [ v ] 表示经过了 S S S 中的所有点,处于 v v v 点时,访问剩余所有节点需要的总权重,然后记忆化搜索即可 无向图前k条不重叠最短路径 对于这种题,与一般最短路径不同的就是要求多条最短路径,一般的做法是使用最小费用流的模板来解决这种问题,每条边的长度为 c i c_i c i ​ ,最大流 f i = 1 f_i=1 f i ​ = 1 ,在图中求流量为 k k k 的最小费用,即前 k

BFS求无权无向图最短路

拜拜、爱过 提交于 2020-03-03 08:24:28
BFS求最短路 假设有一个n行m列网格迷宫,每个宫格要么可以走要么不可以走,设置一个起点和一个终点,如何求起点到终点的最短路径?(图片来自网上) 我们知道BFS广度优先搜索就是按照距离根节点距离从小到大的顺序搜索,因此利用BFS逐步计算出每个节点到起点的最短距离,以及最短路径每个节点的前一个节点,最终将生成一颗以起点为根的BFS树。此时BFS可以求出任意一点到起点的最短距离 下面代码假设起点在(1,1),终点在(n,m),输入时为0代表该处不可通过 #include < iostream > #include < stack > #include < queue > #include < cstring > using namespace std ; const int maxn = 1005 ; struct node { int r , c ; node ( ) { } node ( int a , int b ) : r ( a ) , c ( b ) { } } edge [ maxn ] [ maxn ] ; //存BFS树,也可以优化为链表 int dx [ 4 ] = { - 1 , 1 , 0 , 0 } ; int dy [ 4 ] = { 0 , 0 , - 1 , 1 } ; bool vis [ maxn ] [ maxn ] ; /

最短路径算法 : Dijkstra 和Floyd

爱⌒轻易说出口 提交于 2020-03-03 07:12:00
思想:Dijkstra是求单源最短路径,Floyd算法是用于求多源最短路径,算出来的是所有的节点到其余各节点之间的最短距离。 Dijkstra算法 先遍历一下还没有在最短路中的点,选出一个距离 已经在最短路集合中的点 距离最近的点(遍历与 最短路包含的点 相连的节点),并把它加入到最短路中,并且更新所有点的最短路,直到所有的点都加入到最短路中。 图解参考: https://www.cnblogs.com/Glacier-elk/p/9438077.html 操作步骤 (1) 初始时,S只包含起点s;U包含除s外的其他顶点,且U中顶点的距离为"起点s到该顶点的距离"[例如,U中顶点v的距离为(s,v)的长度,然后s和v不相邻,则v的距离为∞]。 (2) 从U中选出"距离最短的顶点k",并将顶点k加入到S中;同时,从U中移除顶点k。 (3) 更新U中各个顶点到起点s的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。 (4) 重复步骤(2)和(3),直到遍历完所有顶点。 例子 #leetcode1368困难 class Solution: def minCost(self, grid: List[List[int]]) -> int: #0302 30min ''

最短路径算法——迪杰克斯拉算法

戏子无情 提交于 2020-03-03 02:35:52
最短路径算法——迪杰克斯拉算法 Dijkstra算法的思想 1、设置两个顶点集S和T,集合S中存放已经找到最短路径的顶点,集合T中存放着当前还未找到最短路径的顶点; 2、初始状态下,集合S中只包含源点V1,T中为除了源点之外的其余顶点,此时源点到各顶点的最短路径为两个顶点所连的边上的权值,如果源点V1到该顶点没有边,则最小路径为无穷大; 3、从集合T中选取到源点V1的路径长度最短的顶点Vi加入到集合S中; 4、修改源点V1到集合T中剩余顶点Vj的最短路径长度。新的最短路径长度值为Vj原来的最短路径长度值与顶点Vi的最短路径长度加上Vi到Vj的路径长度值中的较小者; 5、不断重复步骤3、4,直至集合T的顶点全部加入到集合S中。 public int [ ] dijkstra ( int v ) { if ( v < 0 || v >= numOfVexs ) throw new ArrayIndexOutOfBoundsException ( ) ; boolean [ ] st = new boolean [ numOfVexs ] ; // 默认初始为false int [ ] distance = new int [ numOfVexs ] ; // 存放源点到其他点的矩离 for ( int i = 0 ; i < numOfVexs ; i ++ ) for ( int j

Navigation System

空扰寡人 提交于 2020-03-02 21:36:22
D - Navigation System 参考: Codeforces Round #625 (Div. 1, based on Technocup 2020 Final Round).B. Navigation System 在遍历这个点A的时候,其实是判断下一个点B是否需要重新规划路径,如果 点B的最短路径!=点A的最短路径-1 ,那么可以说明,点B肯定不在A的最短路径上,那如果等于,则看A的最短路径有几条,如果有多条,那么标准规划路径有可能不会包括B。 对于求每一个点到 t 的最短路径长度,可以用 Dijkstra 进行操作,求单源最短路,存反边即可。 // Created by CAD on 2020/3/2. #include <bits/stdc++.h> #define fi first #define se second #define mst(name, value) memset(name,value,sizeof(name)) #define pii pair<int,int> using namespace std; const int maxn=2e5+5; struct edge{ int v,next,w; }e[maxn<<1]; int cnt=0,head[maxn<<1]; void add(int u,int v,int w) { e[+

图算法:广度优先遍历

試著忘記壹切 提交于 2020-03-02 21:00:05
图的遍历算法包括广度优先遍历和深度优先遍历。其中深度遍历主要用于 解答树问题 的求解,而 深度遍历 往往为了获得 最短路径解 。什么是最短路径解呢?视具体情况而定,比如 最短的迭代步数 。在一般的隐式图中很常见,因为隐式图的规模往往是无穷的。 对于一般问题怎么思考呢?我想主要分三个步骤: 分析问题(解答树or最短路径);套用框架;剪枝优化 。 下面给出广度优先遍历的基本框架,关键词: 队列 。 #include <queue> #include <cstring> #include <cstdio> #define ONLINE 1 using namespace std; int graph[8][8]; int visited[8]; queue<int> q; char s[8]; void bfs(int root) { q.push(root); while (!q.empty()) { int k = q.front(); q.pop(); if (visited[k] != 1) { printf("%d ", k); visited[k] = 1; } for (int j = 0; j < 8; j++) { if (graph[k][j] == 1 && visited[j] != 1) { q.push(j); } } } } int main(int

1003-Emergency

无人久伴 提交于 2020-03-01 12:59:19
As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible. Input Specification: Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) -

最短路径算法--无向图

十年热恋 提交于 2020-03-01 11:18:27
最短路径算法 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法。该算法被称为是“贪心算法”的成功典范。 1、表示图的数据结构 邻接列表 邻接列表 :在邻接列表实现中,每一个顶点会存储一个从它这里开始的边的列表。比如,如果顶点A 有一条边到B、C和D,那么A的列表中会有3条边 邻接列表只描述了指向外部的边。A 有一条边到B,但是B没有边到A,所以 A没有出现在B的邻接列表中。查找两个顶点之间的边或者权重会比较费时,因为遍历邻接列表直到找到为止。 邻接矩阵 邻接矩阵: 在邻接矩阵实现中,由行和列都表示顶点,由两个顶点所决定的矩阵对应元素表示这里两个顶点是否相连、如果相连这个值表示的是相连边的权重。例如,如果从顶点A到顶点B有一条权重为 5.6 的边,那么矩阵中第A行第B列的位置的元素值应该是5.6: 、、 图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:    从上面可以看出,无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的。 从这个矩阵中,很容易知道图中的信息。 (1)要判断任意两顶点是否有边无边就很容易了; (2

A1003 Emergency (25分)

╄→尐↘猪︶ㄣ 提交于 2020-02-29 20:23:37
一、技术总结 这是一道考查Djiktra算法的题目,主要是求解最短路径的前提下,求每个城市点权的最大值,同时最短路径的条数。 只需要在Djikstra算法的基本架构下,添加一些条件即可,点权是添加一个数组weight存储每个点的权值,然后再创建数组w,用于存储。初始化是,除了起点s,w[s]=weight[s],其余都初始化为0,使用memset(w, 0, sizeof(w)),进行初始化。 而对于最短路径的条数,设置数组num,然后初始化,num[s] = 1,其余都是初始化为0,memset(num, 0, sizeof(num))。 还有就是书写的问题,注意关系。具体参考代码。 二、参考代码 #include<bits/stdc++.h> using namespace std; const int maxn = 510; const int INF = 100000000; int n, G[maxn][maxn]; bool vis[maxn] = {false}; int d[maxn];//用于记录最短路径 int num[maxn];//用于记录最短路径的条数 int weight[maxn];//记录城市中可以调动的人数 int w[maxn]; void Djikstra(int s){ fill(d, d+maxn, INF); memset(num, 0,