题目:https://www.luogu.com.cn/problem/P3371
题目思路:很明显的最短路模板问题,而本次我们将用迪杰斯特拉算法解决
迪杰斯特拉算法,首先给定一个起点,以这个起点开始,层层推进,一直推到终点
举个例子
比如下面这一个有向连通图
在这张图中,1号点为起点,每根棕色的边都是由小序号通向大序号的一条有向边,上面的数字代表该边的权值
五边形内存储的是当前从起点到这个点的最短路径,绿色的图案代表这个点已经搜索完毕
首先,起点到起点肯定是个0,而起点1号到达与之所连接的2,3,4号的当前最短路径就是与之连接的边的权值
对嘛,刚开始搜你还要什么自行车嘛,而且1号也就这么整完了就够了,如下
现在,1号已经整明白了,现在到2号的最短路径是4,到3是9,到4是6
本着贪心的原则,我们总是认为越小的开始越有可能找到正确答案
所以将二号当做下一个中间点,继续向下,2号的连接点只有4号
BUT! 从2号到4号走 1-->2-->4 的路径要15个权值,但我们刚刚算着,从起点花6个权值可以直达4号
所以到4号的最短路径不变,还是6,如下
现在,2号点结束,3号是9,4号是6,4号将作为下一个中间点继续向下,易得
现在到3是9,到5是17,到6是20,从3再来一遍
等等,3好像没有向外连接任何东西啊
咳咳。。。。。。虽然没有,但依照国际惯例还要再搜一搜
让程序知道它没有,如下
现在到5是17,到6是20,从5开始,发现5只能连着6,而且顺着5走到6还要多花4个权值
那就不用更新了,直接划掉就好。
最后再依照“国际惯例”跟6知会一声,就过了,成品如下
最后,结果出来了
起点1到
1的最短路径是0
2是4
3是9
4是6
5是17
6是20
至此
接下来便是程序实现
由于用二维数组存储有向边的方式时间复杂度为O(n*n)
所以这里直接上(nlogn)的,更简便的堆优化系列迪杰斯特拉
#include<bits/stdc++.h>
using namespace std;
#define inf 2147483647
//题目已经变相要求了最大值:2^31-1
struct hdb{
int u,v,w,next;
}e[500001];
//在此有向边中,u为起点,v为终点,w为权值
int h[10001],vi[10001],m,n,s,u,v,w,dis[10001],cnt=0;
//h[i]为顶点i所连接的,输入最晚的一条边
//vi判断这个顶点有没有被访问过
//dis[i]代表从起点到这个点i的当前最短路径
struct node{
int w,now;
//w为当前路径,now为起点
inline bool operator <(const node &x)const{
return w>x.w;
}
//重置运算符,告知优先队列的排法,背过
};
priority_queue<node> q;
//优先队列,自动排序,格式背过
void add(int u,int v,int w){
++cnt;//新开一个
e[cnt].u=u;//u为起点
e[cnt].v=v;//v为终点
e[cnt].w=w;//w为权值
e[cnt].next=h[u];
//将上一条以其作为起点的边放入
h[u]=cnt;
//再把当前这条晚边放入
}
void dijkstra(){
for(int i=1;i<=n;++i){
dis[i]=inf;//初始化
}
dis[s]=0;//起点到起点的距离是0
q.push((node){0,s});//存入
while(!q.empty()){//还有没搜过的点
node p=q.top();
//顶端权值最小的导出来
q.pop();
u=p.now;//起点导出来
if(vi[u]==1){
continue;
}//如果被访问过就跳过
vi[u]=1;//如果没有就设定为被访问
for(int i=h[u];i;i=e[i].next){
//从最后一条晚边逐一向上搜索
int v=e[i].v;//取终点
if(dis[v]>dis[u]+e[i].w){
//如果绕路走比直达所需权值要少
dis[v]=dis[u]+e[i].w;
//更新
q.push((node){dis[v],v});
//插入这个终点作为以后的新起点
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&s);
//输入
for(int i=1;i<=m;++i){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
//输入并加入
}
memset(vi,0,sizeof(vi));
//归零
dijkstra();
for(int i=1;i<=n;++i){
printf("%d ",dis[i]);
}//输出
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】