本文最后更新于 33 天前,其中的信息可能已经有所发展或是发生改变。
Dijkstra求最短路,从节点1开始,求节点n到1的最短路径,定义一个数组dist表示节点到1的距离,dist[1]就等于0,然后循环查找n个节点中没被找过的并且距离1最近的点,然后遍历与这个点相连的节点并且更新dist数组,当n个节点都被找过后,dist[n]中就是n到1的最短路径
Dijkstra求最短路 I
给定一个 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 = 1e5+10;
int e[N*2],ne[N*2],b[N*2],h[N],idx,n,m;
int a[N],st[N];
void add(int x,int y,int z){
e[idx]=y;
ne[idx]=h[x];
b[idx]=z;
h[x]=idx++;
}
void Dijkstra(){
memset(a,0x3f,sizeof a);
a[1]=0;
for(int k=0;k<n;k++){
int t=-1;
for(int i=1;i<=n;i++){
if(st[i]==0&&(t==-1||a[i]<a[t])){
t=i;
}
}
st[t]=1;
// cout<<a[t]<<" "<<t<<" "<<st[t]<<endl;
for(int i=h[t];i!=-1;i=ne[i]){
int j = e[i];
a[j]=min(a[j],a[t]+b[i]);
}
}
}
int main(){
memset(h,-1,sizeof h);
cin>>n>>m;
for(int i=0;i<m;i++){
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
Dijkstra();
if(a[n]==0x3f3f3f3f)cout<<-1<<endl;
else cout<<a[n]<<endl;
return 0;
}
Dijkstra求最短路 II
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为非负值。
请你求出 1号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。
输入格式
第一行包含整数 n 和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 −1。
数据范围
1≤n,m≤1.5×105,
图中涉及边长均不小于 0,且不超过 10000。
数据保证:如果最短路存在,则最短路的长度不超过 109。
输入样例:
3 3
1 2 2
2 3 1
1 3 4
输出样例:
3
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int e[N*2],ne[N*2],b[N*2],h[N],idx,n,m;
int a[N],st[N];
void add(int x,int y,int z){
e[idx]=y;
ne[idx]=h[x];
b[idx]=z;
h[x]=idx++;
}
void Dijkstra(){
memset(a,0x3f,sizeof a);
a[1]=0;
//优先队列默认是大根堆,如果要构造小根堆就要输入三个参数priority_queue<元素类型, 底层容器类型, 比较函数>
//指定比较函数时第二个参数没有默认值,所有需要指定
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>qe;//定义小根堆
qe.push({0,1});
while(qe.size()){
// for(int i=1;i<=n;i++){
// if(st[i]==0&&(t==-1||a[i]<a[t])){
// t=i;
// }
// }
auto tt = qe.top();
qe.pop();
int t = tt.second;
if(st[t])continue;
st[t]=1;
// cout<<a[t]<<" "<<t<<" "<<st[t]<<endl;
for(int i=h[t];i!=-1;i=ne[i]){
int j = e[i];
if(a[j]>a[t]+b[i]){
a[j]=a[t]+b[i];
qe.push({a[j],j});
}
}
}
}
int main(){
memset(h,-1,sizeof h);
cin>>n>>m;
for(int i=0;i<m;i++){
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
Dijkstra();
if(a[n]==0x3f3f3f3f)cout<<-1<<endl;
else cout<<a[n]<<endl;
return 0;
}