DAY3
1.AcWing 849. Dijkstra求最短路 I
考察点:朴素Dijkstra,求最短路问题
基础知识点:
(1)最短路(存在权重)
在图论中:源点就是起点,汇点就是终点
n是点的数量,m是边的数量
最短路知识结构图:
(2)朴素Dijkstra算法 适合用于稠密图
s是当前已确定最短距离的点
伪代码:
解题步骤:
进行n(n为n的个数)次迭代去确定每个点到起点的最小值 最后输出的终点的即为我们要找的最短路的距离
dist[n] //用于存储每个点到起点的最短距离
st[n] //用于在更新最短距离时 判断当前的点的最短距离是否确定 是否需要更新
总而言之:第一步就是遍历n个数,首先找出t(没有确定并且距离起点最近的点),并且以t为中转站对后面的数进行更新,邻接矩阵存的是两点的距离。
注:稠密图用邻接矩阵来存储,稀疏图用领接表来存储 本题用有向图
解题模板:
#include<iostream>
#include<cstring>
#include<algorithm>
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); //初始化距离 0x3f代表无限大
dist[1] = 0;//第一个点到自身的距离为0
for(int i=0;i<n;i++)//有n个点所以要进行n次 迭代
{
int t = -1;//用来存储当前点
for(int j=1;j<=n;j++)//这里的j代表的是从1号点开始
if(!st[j]&&(t==-1||dist[t]>dist[j]))
{
t = j;
}
st[t] = true;
for(int j=1;j<=n;j++)//以t为中转站,依次更新每个点所到相邻的点路径值
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
if(dist[n]==0x3f3f3f3f) return -1; //如果第n个点路径为无穷大即不存在最低路径
return dist[n];
}
int main()
{
scanf("%d%d", &n, &m);
memset(g, 0x3f, sizeof g);//初始化时无限大是0x3f3f,最后判断的时候为啥是0x3f3f3f3,因为0x3f按照4字节填充就是0x3f3f3f3f
//初始化图 因为是求最短路径
//所以每个点初始为无限大
while(m--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);//如果第一次输入1 2 3,那么就是g[1][2] = 3
g[a][b] = min(g[a][b], c);//如果发生重边的情况则保留最短的一条边
}
printf("%d\n", Dijkstra());
return 0;
}