Dijkstra是一个求单源最短路径的算法。
"单源最短路径",顾名思义,从一个源头到其他结点的最短路径。而这个算法,可以求出单个点对其他所有点的最短路径长度。(有些情况是Dijkstra不能处理的,比如负边权,遇到这类情况可能就需要使用其他算法了)
主要思想:
从源结点开始,遍历源结点的所有连接的边,并进行排序,再从边的值最小的一个边开始遍历,在每一次遍历的过程中,都尝试更新所储存的某个结点对于源结点的最短路径长度(假设我们要到点B,目前我们遍历到了点A,如果点A到点B的距离加上点A到源点的距离比目前我们之前存储的 源点到点B的距离短的话,就更新源点到点B的最短路径,并在之后遍历连着点B的点(也就是进行BFS))。
例子:
首先,从源结点开始进行BFS(也就是遍历到达的点所向外连着的点.比如A->B B->A A->C(A连B,B连A,A连C),那么BFS A结点就是B C)
在BFS的过程中,每到一个点,就比较一下从 源头到这个点的路径长度 和 之前求的从源头到这个点的最短路径的长度 大小,如果现在这个路径长度比较小,就存起来
模板题目地址:https://www.luogu.org/problemnew/show/P4779
#include
#include
#include
#include
using namespace std;
int s,cnt=0,dis[1000010],head[1000010];
//s:源结点 cnt:边总数,用于存边 dis:存储当前的源结点到某个结点的最短路径长度(下标是结点序号) head:邻接表,
struct Edge{
int v,w,nxt;
}e[500010];
struct Node{
int u,d;
bool operator <(const Node& rhs)const{
return d>rhs.d;//重载运算符,这个需要背过
}
};
void addEdge(int u,int v,int w){
e[++cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
//关于邻接表:
//首先要明确,邻接表是一个链式结构,也就是说,首先添加的边在邻接表的最后面
//最后添加的在前面,在遍历的时候也是从头往后遍历,也就是说最先添加的反而最后被遍历到.
//当遍历到最后一个的时候 由于最后一个的后面已经没有结点了,那么此时i的值就成为了0(具体看下面的for循环代码)
//成为0了,也就代表着循环该结束了.这时候,循环条件不成立,循环就结束了.
head[u]=cnt;
}
void dijkstra(){
dis[s]=0;
priority_queueq;
q.push((Node){s,0});
while(!q.empty()){
Node now=q.top();q.pop();
int d=now.d,u=now.u;
if(d!=dis[u])continue;//堆优化,等同于 if(d>dis[u])continue;,可以相对较好地减少时间复杂度
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v,w=e[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push((Node){v,dis[v]});
}
}
}
}
int main(){
int n,m;
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=n;i++)dis[i]=2147483647;//将源结点到其他结点的路径长度初始化为尽可能大的值,也就是INF
for(int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addEdge(x,y,z);
}
dijkstra();
for(int i=1;i<=n;i++)printf("%d ",dis[i]);
return 0;
}
#include
#include
#define P pair
#define INF 2147483647
#define maxn 500005
using namespace std;
priority_queue,greater
>q;
int dis[maxn],vis[maxn],head[maxn];
int n,m,s;
int cnt;
struct Edge{
int u,v,w,next;
}e[maxn*2];
void add(int u,int v ,int w){
e[++cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt;
}
void dijkstra(){
while(!q.empty()){
int x=q.top().second;
q.pop();
if(!vis[x]){
vis[x]=1;
for(int i=head[x];i;i=e[i].next){
int v=e[i].v;
dis[v]=min(dis[v],dis[x]+e[i].w);
q.push(make_pair(dis[v],v));
}
}
}
}
int main(){
cin>>n>>m>>s;
for(int i=1;i<=m;i++){
dis[i]=INF;
}
dis[s]=0;
q.push(make_pair(0,s));
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
dijkstra();
for(int i=1;i<=n;i++){
cout<