【No.17】蓝桥杯图论上|最短路问题|Floyd算法|Dijkstra算法|蓝桥公园|蓝桥王国(C++)

本文介绍了图的基本概念、存储方式,以及最短路问题的相关算法。图由点和边构成,存储方式有数组存边、邻接矩阵、邻接表和链式前向星等。最短路算法包括Floyd和Dijkstra,前者基于动态规划,能求所有点对间最短路径;后者基于贪心思想,处理无负权边图的单源最短路径问题。

图的基本概念

图:

  • 由点(node,或者 vertex)和连接点的边(edge)组成。
  • 图是点和边构成的网。
    树:
  • 特殊的图
  • 树,即连通无环图树的结点从根开始,层层扩展子树,是一种层次关系,这种层次关系,保证了树上不会出现环路。
  • 两点之间的路径:有且仅有一条路径。
  • 最近公共祖先。
图应用背景
  • 地图:路口、道路、过路费
  • 计算机网络:路由协议
  • 人际关系:六度空间理论
图的种类
  1. 无向无权图,边没有权值、没有方向;
  2. 有向无权图,边有方向、无权值;
  3. 加权无向图,边有权值,但没有方向;
  4. 加权有向图;
  5. 有向无环图(Directed Acyclic Graph,DAG)。
图算法的时间分析

图算法的复杂度和边的数量 E、点的数量 V 相关。
O(V+E):几乎是图问题中能达到的最好程度。
O(VlogE)、O(ElogV):很好的算法。
O(V2)、O(E2)或更高:不算是好的算法。

图的存储

能快速访问:图的存储,能让程序很快定位结点 uv 的边(u, v)

  • 数组存边:简单、空间使用最少;无法快递定位
  • 邻接矩阵:简单、空间使用最大;定位最快 dis[a][b]
  • 邻接表:空间很少,定位较快
  • 链式前向星:空间更少,定位较快
    注: 存储方式跟题目相匹配,占用空间少定位快也不一定是问题的最优存储方式。
数组存边

优点:简单、最省空间。
缺点:无法定位某条边。
应用:bellman-ford 算法、最小生成树的 kruskal 算法

struct Edge
{
    int from, to, dis;  //from起始点,to终止点,dis权值
}e[M]; //结构体数组存边

cin >> n >> m;

for(int i = 1; i <= m; ++ i)
    cin >> e[i].from >> e[i].to >> e[i].dis;
邻接矩阵

二维数组: graph[NUM][NUM]
无向图: graph[i][j] = graph[j][i]
有向图: graph[i][j] != graph[j][i]
权值: graph[i][j]存结点i到j的边的权值。 例如 graph[1][2]=3,graph[2][1]=5等等。 用 graph[i][j]=INF表示i,j之间无边。

优点:
  • 适合稠密图;
  • 编码非常简短;
  • 对边的存储、查询、更新等操作又快又简单。
缺点:
  • 存储复杂度 O(V^2)太高。V=10000 时,空间 100M。
  • 不能存储重边。
邻接表和链式前向星

邻接表(指针或数组下标)和链式前向星(容器模拟)的思路一样,只是表达方式不同。
应用场景:大稀疏图

优点:
  • 存储效率非常高,存储复杂度O(V+E)
  • 能存储重边
    图片描述
struct edge{
   
   
    int from, to; long long w; //起点,终点,权值。起点from并没有用到,e[i]的i就是from
    edge(int a, int b,long long c){
   
   from=a; to=b; w=c;}
};
vector<edge>e[N];          //用于存储图

最短路问题

最广为人知的图论问题就是最短路径问题。
简单图的最短路径

  • 树上的路径:任意 2 点之间只有一条路径
  • 所有边长都为 1 的图:用 BFS 搜最短路径,复杂度 O(n+m)
    普通图的最短路径
  • 边长:不一定等于 1,而且可能为负数
  • 算法:FloydDijkstraSPFA 等,各有应用场景,不可互相替代
最短路算法比较
问题 边权 算法 时间复杂度
一个起点,一个终点 非负数; 无边权(或边权为 1) Astar(K短路)/ 普通 <O((m+n)logn)
双向广搜 <O((m+n)logn)
贪心最优搜索 <O(m+n)
一个起点到其他所有点 无边权(或边权为 1) BFS O(m+n)
非负数 Dijkstra(堆优化 优先队列) O((m+n)logn)
允许有负数 SPFA <O(mn)
所有点对之间 允许有负数 Floyd-Warshall O(n^3)

什么算法也不能解决存在负环图的最短路的问题!最多是判断是否存在,或者找到负环。

网站推荐:CSAcademy Graph Editor
图片描述
方便图论的学习。

Floyd 算法

  • 最简单的最短路径算法,代码仅有 4 行
  • 存图:最简单的矩阵存图
  • 易懂,比暴力的搜索更简单易懂。
  • 效率不高,不能用于大图
  • 在某些场景下有自己的优势,难以替代。能做传递闭包问题(离散数学)
for(int k = 1; k <= n; k ++)         //floyd的三重循环
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= n;<
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值