Dijkstra算法
Dijkstra算法算是贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的,所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。
问题引入:
指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。例如求下图中的1号顶点到2、3、4、5、6号顶点的最短路径。
下面我们来模拟一下:
代码:
1 //邻接矩阵是用列模拟每一个点,每一行来表示每一列表示的点到每个点的距离
2 //如果能走到则距离为具体数字若不能走到则为无穷大即0x3f3f3f3f
3 //朴素Dijkstra算法实质找到每个点到每个点的最短距离中的最小距离
4 //并且更新d[],更新1号点到其他点的距离
5 //再从这个最短距离的点去寻找其能寻找到的最短的距离
6 #include<iostream>
7 #include<cstring>
8 #include<algorithm>
9 using namespace std;
10 const int N=505;
11 int n,m;
12 int q[N][N],d[N];//q储存稠密图的邻接矩阵d储存1到每个点的最小距离
13 bool st[N];//标记每个数是否被找到最短距离
14 int dijkstra()
15 {
16 d[1]=0;
17 for(int i=1;i<=n;i++)//由于这里是从0开始遍历并且除了d[1]其他都是0x3f3f3f3f,所以第一次找到的最小距离的下标就是1,因此这样就可以把dist距离更新为1号点到其他点的距离
18 {
19 int t=-1;
20 for(int j=1;j<=n;j++)//遍历一遍d
21 {
22 if(!st[j]&&(t==-1||d[j]<d[t]))//如果没有找到最短距离并且t没有更新或者有更短的距离
23 t=j;
24 }
25 st[t]=true;
26 for(int j=1;j<=n;j++)
27 d[j]=min(d[j],d[t]+q[t][j]);//松弛操作
28 //此处为即为1->t->j 更新1到j的最短距离就用1到t的距离加上t到j的距离
29 }
30 if(d[n]!=0x3f3f3f3f) return d[n];
31 else return -1;
32 }
33 int main()
34 {
35 cin>>n>>m;
36 memset(q,0x3f,sizeof q);//给每个数赋值为无穷大,无穷大的数值0x3f3f3f3f字节为0x3f
37 memset(d,0x3f,sizeof d);
38 while(m--)
39 {
40 int a,b,c;
41 cin>>a>>b>>c;
42 q[a][b]=min(q[a][b],c);//可能有重边且权重不同
43 }
44 cout<<dijkstra()<<endl;
45 return 0;
46 }