dijkstra算法用于单源最短路的计算,给定一个 n 个点 m 条边有(无)向图,可以计算 1 到其他任意一点的最短路径。
复杂度:(O n ^ 2,由于使用邻接矩阵存储,所以空间复杂度也为O(n ^ 2),一般用于稠密图的单元最短路。
不能用于计算带负权边的图
原因:
模板题:
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1 。
输入格式
第一行包含整数 n 和 m 。
接下来 m 行每行包含三个整数 x,y,z ,表示存在一条从点 x 到点 y 的有向边,边长为 z 。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 −1 。
数据范围
1≤n≤500 ,
1≤m≤105 ,
图中涉及边长均不超过10000。
输入样例:
3 3
1 2 2
2 3 1
1 3 4
输出样例:
3
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
int n,m,g[N][N];
int d[N];//表示1到N的最短路径长度
int st[N];
int dijkstra()
{
memset(d,0x3f,sizeof(d));
d[1] = 0;//1 - 1长度为0
for(int i = 1; i <= n; i ++ )//n次循环将n个点入集合
{
int t = -1;
for(int j = 1; j <= n; j ++ )//找到离起点最近的点
if(!st[j] && (t == -1 || d[j] < d[t]))//不要忘了 t == -1
t = j;
st[t] = 1;//标记,进入集合
for(int j = 1; j <= n; j ++ )//更新其他点的离起点距离!!!起点很重要
//if(!st[j]) 可要可不要
d[j] = min(d[j],d[t] + g[t][j]);
}
if(d[n] == 0x3f3f3f3f)
return -1;
else
return d[n];
}
int main()
{
cin>>n>>m;
memset(g,0x3f,sizeof(g));
for(int i = 1; i <= m; i ++ )
{
int a,b,c;
cin>>a>>b>>c;
g[a][b] = min(g[a][b],c);//存在重边取最短
}
int t = dijkstra();
cout<<t;
return 0;
}