这里写目录标题
前言
图论一直是我最头疼的东西 ——2021/9/4
现在我终于不头疼啦
在dijkstra上磨了一天的我终于把他彻底悟透了
关于图论
图论一直都是比赛中压轴的题目,也是一个难点
在普及组中,图论一般都是考储存和最短路
我们最先接触的图应该就是树了,树是图的一种,他延伸出来的bfs,也是最短路的一种:没有边权的最短路,所以图论,博大精深
关于路径的松弛
举个例子,小明直接到小刚家距离是100米,小刚直接到小红家是50米,小明直接到小红家是300米,请问小明到小红家最短多少米?
这很简单吧,从小刚家再转到小红家,需要150米,
这就是松弛,在原本路程远的基础上,“绕路”使路程变短
图的储存
邻接矩阵
优点:容易理解
缺点:空间时间的限制都很大
思想与演示
邻接矩阵,是一种思想最简单的储存方法
存图,就是要存顶点与顶点的关系
而邻接矩阵,就是像下面的表:
\ | v1 | v2 | v3 |
---|---|---|---|
v1 | 0 | ∞ | ∞ |
v2 | ∞ | 0 | ∞ |
v3 | ∞ | ∞ | 0 |
(为了这个表格我还特意去研究了一下Markdown)
如其所表示,邻接矩阵就是以一个二维数组为基本,表达v1,v2,v3边的关系,如果有连接,那么就有值,没有连接,那么就没值。
代码实现邻接矩阵存储
#include <iostream>
#define INF 0x3f3f3f3f //INF指无穷大,在int范围内
using namespace std;
const int N=1e3; //因为空间问题,邻接矩阵只能存到1000
int n,m; //n个顶点,m个边
int arcs[N][N];
int main(){
cin>>n>>m;
cin>>u>>v>>w;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
arcs[i][j]=INF;
}
}
for(int i=1;i<=m;i++){
//m个顶点的输入
cin>>u>>v>>w;
arcs[u][v]=w;
arcs[v][u]=w;
}
}
关于邻接矩阵的最短路(Floyd)
邻接矩阵可不可以做最短路呢
邻接矩阵有一个专门的最短路算法:Floyd
Floyd就是在邻接矩阵的基础上,对边进行松弛
具体实现,我们就可以模仿上面说的松弛
伪代码:
v1->v2=min(v1->v2,v1->v3+v3->v2);
差不多就是这样吧
代码该咋实现呢
代码实现Floyd最短路
#include <iostream>
#define INF 0x3f3f3f3f //INF指无穷大,在int范围内
using namespace std;
const int N=