最近稍微学习了最短路算法后,为了记录学习过程(为了交作业),关于洛谷p1399问题的理解(dijkstra算法)
最短路简单介绍
就是在以及许多点,然后许多路程,方向后,求某个点到另一个点消耗的最下权重(可能不同的题目有不同的说法)。(确实是简单介绍)
dijkstra 核心代码
for(int i=0; i<n; i++)//更新n个点(包括起点自身)到起点的权重
{
int t = -1;
for(int j=1; j<=n; j++) // 在没有确定最短路中的所有点找出距离最短的那个点 t
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]);//实际上这里有很多多余步骤,因为st[]=ture的点已经不需要t来更新(已经是最小的),所以有堆优化版的dijkstra算法,这里就不说了,因为我就会这个0.0.
}
关于洛谷那题目
题目描述
有一个 n个点m条边的无向图,请求出从s 到 t的最短路长度。
输入格式
第一行四个正整数 n,m,s,t, 接下来 m 行,每行三个正整数 u,v,w,表示一条连接 u,v,长为 w 的边。
输出格式
输出一行一个整数,表示答案。
输入输出样例
输入
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1
输出
7
因为是无向边,所以要稍微改一点,下面是代码
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int N = 2510;
int sta,en;//第几个点出发到第几个点
int n,m;
int g[N][N]; // 表示两点之间距离
int dist[N]; // 第 i 个点到起点的最短距离
bool st[N]; // 代表第 i 个点的最短路是否确定、是否需要更新
int dijkstra()
{
memset(dist,0x3f,sizeof(dist)); // 将所有距离初始化正无穷
dist[sta] = 0; // 第一个点到起点的距离为 0
st[sta]=true;//将起点确定最短路,并更新周围的点
for(int j=1; j<=n; j++)
dist[j] = min(dist[j],dist[sta]+g[sta][j]);
for(int i=0; i<n-1; i++)//开始循环,因为之前起点单独过了一遍,所以只要n-1
{
int t = -1;
for(int j=1; j<=n; j++) {// 在没有确定最短路中的所有点找出距离最短的那个点
if(j==sta){continue;}
if(!st[j] && (t == -1 || dist[t] > dist[j]))
t=j;
}//循环结束t存的是没有确定节点中离起点最近点的编号
st[t]=true; //代表 t 这个点已经确定最短路了
for(int j=1; j<=n; j++) // 用 t 更新其他点的最短距离
dist[j] = min(dist[j],dist[t]+g[t][j]);
}
return dist[en];
}
int main()
{
cin >> n >> m>>sta>>en;
memset(g,0x3f,sizeof(g));
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a] = min(g[a][b],c); // 保留长度最短的重边
}
cout << dijkstra();
return 0;
}
如果想了解更多请移步这篇超详细的博客
希望文章对你能一点点作用,如果有什么问题欢迎批评指正,不胜感激!
0.0