算法之图论(二)有权最短路
文章目录
- 一、Floyd算法(多源)
- 二、Dijkstra算法(单源)
有权图:我们把带有权值的称为有权图。
边权:可以理解为两点之间的距离或费用。
最短路径: 从源点到终点之间的所有路径中,边权之和最小的那一条路径,称为这两点之间的最短路径。
(1) 多源最短路径问题:求任意两点之间的最短路径。Floyd算法
(2) 单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径。
常用有Dijkstra算法,Ford算法,SPFA算法。
一、Floyd算法(多源)
需要利用邻接矩阵存储图,
例如,对于上图求1,4之间的最短路径;
D[i][j]即为最短路径的长度.
本质为动态规划算法
算法时间复杂度为
,适用于出现负边权的情况.
注意邻接矩阵的初始化问题!
无向图
#include<bits/stdc++.h>
using namespace std;
int D[51][51];
const int oo = 0x7f;
int main(){int i,j,k,x,y;int N,M;cin >> N >> M;//初始化for(int i = 1;i <= N; i++){for(int j = 1; j <= N; j++){if(i != j){D[i][j] = oo;}}}for(int i = 1; i <= M; i++){int w;cin >> x >> y;D[x][y] = D[y][x] = w;}for(int i = 1; i <= N; i++){for(int j = 1; j <= N; j++){for(int k = 1; k <= N; k++){if(D[i][k] + D[k][j] < D[i][j]){D[i][j] = D[i][k] + D[k][j];}}}}cout << D[1][4];
}
二、Dijkstra算法(单源)
Dijkstra算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径,适用于权值非负的有向或无向图.效率低于Floyed算法.
Dijkstra算法类似于Prime算法,采用贪心策略,将图中的顶点分为已求出最短路径的顶点集合,和其余尚未确定最短路径的顶点集合(蓝白点思想).每次找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离.
假设已经求出最短路径的顶点集合为S,尚未确定最短路径的顶点集合为T,我们
(1)
S中只包含一个顶点,即源点u.若其他点i与源点有边,则dis[i]值为边的权值,反之为oo.
(2)
从T中选取一个顶点k,使其到源点的距离最小。将k加入s,更新dis[k].
(3)
以k点为新考虑的中间点,修改T中的dis值;若从源点u到顶点v经过k的距离比原来距离短,则修改dis[v].
(4)
重复步骤(2)和(3),直到所有顶点包含在S中。
A | B | C | D | E | F |
---|---|---|---|---|---|
0 | 2 | 3 | 5 | oo | oo |
A | B | C | D | E | F |
---|---|---|---|---|---|
0 | 2 | 3 | 5 | 6 | oo |
A | B | C | D | E | F |
---|---|---|---|---|---|
0 | 2 | 3 | 4 | 6 | oo |
A | B | C | D | E | F |
---|---|---|---|---|---|
0 | 2 | 3 | 4 | 6 | 6 |
A | B | C | D | E | F |
---|---|---|---|---|---|
0 | 2 | 3 | 4 | 6 | 6 |
A | B | C | D | E | F |
---|---|---|---|---|---|
0 | 2 | 3 | 4 | 6 | 6 |
#include<bits/stdc++.h>
using namespace std;
// const int N = 100;
const int INF = 0x7f;
int N,M;
int dis[51]; //存储最小路径
int mat[51][51]; //存储边权
bool vis[51]; //记录是否求出最短路径
int pos = 1;
//求从源点1到n的最短路径
void Dijkstra(int n){memset(vis,true,sizeof(vis));for(int i = 1; i <= n; i++) dis[i] = mat[1][i];vis[1] = false;dis[1] = 0;for(int i = 1; i <= n; i++){int mis = INF;for(int j = 1; j <= n; j++){if(vis[j] && dis[j] < mis){mis = dis[j];pos = j;}}vis[pos] = false;for(int j = 1; j <= n; j++){if(vis[j] && dis[j] > dis[pos] + mat[pos][j]){dis[j] = dis[pos] + mat[pos][j];}}}cout << dis[n];
}
int main(){cin >> N >>M;for(int i = 1; i <= N; i++){for(int j = 1; j <= N; j++){if(i == j){mat[i][j] = 0;}else{mat[i][j] = INF;}}}for(int i = 1; i <= M; i++){int x,y,w;cin >> x >> y >> w;mat[x][y] = mat[y][x] = w;}Dijkstra(N);
}
/*
6 7
1 2 2
1 3 3
1 4 5
2 5 4
3 4 1
4 5 2
4 6 2
*/
例题:
Input:
输入包含多组数据,每组数据第一行是两个整数,N,M(N<=100,M<=10000),N表示城都的大街上有几个路口,标号为1的路口时商店所在地,标号为N的路口时商场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示路口A与路口B之间有一条路,我们的工作人员需要C分治的时间走过这条路。输入保证至少存在1条商店到赛场上的路线。
Output:
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间。
Sample Input:
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output:
3
2
注意:每次都需要对邻接矩阵进行初始化,所以我们封装成函数。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f;
const int N = 110;
int mat[110][110]; //邻接矩阵
int dis[110]; //距离
bool vis[110]; //标记是否访问
void Dijkstra(int n) //Dijkstra算法
{memset(vis, true, sizeof(vis));int pos = 1;for (int i = 1; i <= n; i++){dis[i] = mat[1][i];}vis[1] = 0;for (int i = 1; i <= n; i++){int mis = INF;for (int j = 1; j <= n; j++){if (vis[j] && dis[j] < mis){mis = dis[j];pos = j;}}vis[pos] = false;for (int j = 1; j <= n; j++){if (vis[j] && dis[j] > dis[pos] + mat[pos][j]){dis[j] = dis[pos] + mat[pos][j];}}}cout << dis[n] << endl;
}
void init() //初始化邻接矩阵
{for (int i = 1; i <= N; i++){for (int j = 1; j <= N; j++){if (i == j){mat[i][j] = 0;}else{mat[i][j] = INF;}}}
}
int main()
{ int n,m;while(cin >> n >> m){if(n == 0 && m == 0){break;}init();for(int i = 1; i <= m; i++){int x,y,w;cin >> x >> y >> w;mat[x][y] = mat[y][x] = w;}Dijkstra(n);}
}
算法之图论(二)有权最短路相关推荐
- 坐在马桶上看算法:只有五行的Floyd最短路算法
坐在马桶上看算法:只有五行的Floyd最短路算法 此算法由Robert W. Floyd(罗伯特·弗洛伊德)于1962年发表在"Communications of the ACM" ...
- 【算法】只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字 ...
- 沃舍尔算法_坐在马桶上看算法:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表 ...
- 图论 物联网_图论算法-和图论算法相关的内容-阿里云开发者社区
数学建模需掌握的知识总纲 数学建模需要掌握许多知识,这里我列出总纲: 学建模中的算法 穷举法 神经网络 模拟退火 遗传算法 图论算法 蒙特卡洛算法 所需基础知识 高等数学 线性代数(矩阵加减乘除) 概 ...
- 七桥问题c语言程序数据结构,数据结构与算法学习——图论
什么是图? 在计算机程序设计中,图结构也是一种非常常见的数据结构 但是图论其实是一个非常大的话题 图结构是一种与树结构有些相似的数据结构 图论是数学的一个分支,并且在数学概念上,树是图的一种 它以图为 ...
- 连通域最小外接矩形算法原理_算法|图论 2W字知识点整理(超全面)
作者:SovietPower✨ 链接:https://ac.nowcoder.com/discuss/186584 来源:牛客网 度数序列 对于无向图, 为每个点的度数.有 (每条边被计算两次).有偶 ...
- 基于马尔可夫过程的一种新型混合PSO粒子群算法(SCI二区高被引文献)介绍及算法复现(使用chatgpt)
以下是一篇算法领域的SCI二区文献(原文见附件),介绍了一种使用Markov概率转移矩阵对种群拓扑结构进行加权的粒子群算法,相比于标准PSO算法该算法提高了全局覆盖率,更容易跳出局部最优,但是在局部最 ...
- 深度学习应用篇-计算机视觉-语义分割综述[5]:FCN、SegNet、Deeplab等分割算法、常用二维三维半立体数据集汇总、前景展望等
[深度学习入门到进阶]必看系列,含激活函数.优化策略.损失函数.模型调优.归一化算法.卷积模型.序列模型.预训练模型.对抗神经网络等 专栏详细介绍:[深度学习入门到进阶]必看系列,含激活函数.优化策略 ...
- 【Python数学建模常用算法代码(二)之BP神经网络】
Python数学建模常用算法代码(二) BP神经网络模型Python代码 import numpy as np import math import random import string impo ...
最新文章
- matlab 2010无法运行程序,matalb r2010a安装后打开出现一系列警告,无法运行,哪位大神帮...
- c语言综合性实验数字益智游戏排行榜,C语言综合性实验报告1.doc
- rest_framework框架实现之(认证)
- 给普通用户赋予docker权限
- Python 数据处理函数 round()、int()、floor()、ceil()的用法
- 手写单隐层神经网络_鸢尾花分类(matlab实现)
- android intent传对象,startActivityForResult使用, setResult(RESULT_OK)使用,getArguments(),
- 这该死的高度,height,clientHeight,scrollHeight,offsetHeight
- 调查:拉丁美洲25%的信用卡用户希望使用加密货币付款
- 恶意点击软件测试简历,亲测百度竞价的恶意点击:60%广告费浪费
- 【写给初发论文的人】撰写综述性科技论文常见问题
- prompt综述(截至2021.12.1)
- 闪电贷攻击又背锅? “幕后元凶”竟是它!
- 25个常用的防火墙规则
- 莫比乌斯(mobius)笔记
- MATLAB计算黎曼积分曲线围成的面积
- 大数据-玩转数据-MaxCompute窗口函数
- linux 读取png图片大小,读取 png 图片的宽高信息
- Linux权限相关问题
- 转: std::string用法详解