目录
名词解释:n:通常代表点数 m:通常代表边数
源:起点 单源:一个起点 多源:多个起点
汇点:终点
入度:有多少条边指向我
出度:以这个点为起点出去的边数
边权:离散数学或数据结构中,图的每条边上带的一个数值,他代表的含义可以是长度等等,这个值就是边权
框架图:
朴素的Dijkstra算法:
由于它的时间复杂度是O(N^2)边数与时间复杂度无关,所以它适合做稠密图
稠密图:边数是点数的2~3倍
Dijkstra模板:
例题:Dijkstra求最短路
给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1
思路解析:有贪心的感觉,每次我都选择离我距离最小的那条走,然后最1~j的最短距离就变成
1~t点的距离 t~j的最短距离
建议自己看着代码自己在图上模拟一下,会感受到这个算法之妙!!!
#include<iostream>
using namespace std;
const int N = 510;
int n, m;
int g[N][N];//采用邻接矩阵存储
int dist[N];//距离数组
bool st[N];//判断数组
int dijkstra()
{
memset(dist, 0x3f, sizeof dist);//初始化数组的值为一个很大的数1e9
dist[1] = 0;//将第1号点的到自身的距离初始化为0
for (int i = 0; i < n; i++)
{//n次迭代
int t = -1;//随便的一个没有意义的数即可:目的是下面的寻找出2~n内距离点1最小的数
for (int j = 1; j <= n; j++)//从1开始遍历:注意这个细节
{
if (!st[j] && (t == -1 || dist[j] < dist[t]))//如果该点未被走过
{
t = j;//相当于寻找最小值 1~1 1~2
}
}
st[t] = 1;//标记已经用过了这个点
for (int j = 1; j <= n; j++)//遍历1号点到n号点
{//更新距离
dist[j] = min(dist[j], dist[t] + g[t][j]);//1~j点的距离变为了:1~t的距离+t~j的距离
}
}
if (dist[n] == 0x3f3f3