请见上篇文章(23条消息) 【图论】Dijkstra算法(基础版)_SY奇星的博客-CSDN博客
关于存图,我们可以使用链式前向星进行优化。在贪心找最小边搭桥的时候,我们可以使用优先队列进行优化。
P4779 【模板】单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
详细我是真不想写了,代码中的注释也写的比较明白了,您也可以见这道题的题解,那边也有较详细的讲解。
#include
#define maxn 500010
using namespace std;
int n,m,s; //点,边,起点
int dis[maxn],vis[maxn]; //同基础版
//链式前向星
struct Edge{
int u,v,w,next;
}edge[maxn<<1]; //要乘2,以防为双边,即无向边
int head[maxn];
//优先队列
struct node{
int u,w;
bool operator < (const node &x) const{ //运算符重载
return x.wv是从大到小;
}
};
int tot=0; //加边计数器
inline void add(int u,int v,int w){
edge[++tot]=(Edge){u,v,w,head[u]};
head[u]=tot;
}
void dijkstra(){
for(int i=1;i<=n;i++) dis[i]=0x7fffffff; //初始化数组
dis[s]=0;
priority_queue q;
q.push((node){s,0}); //第一个点入队,进行搭桥
while(!q.empty()){
node temp=q.top();q.pop(); //相当于int u=q.top().u
int u=temp.u; //搭桥点
if(vis[u]) continue; //用过就不再用了
vis[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v,w=edge[i].w;
if(dis[u]+w>n>>m>>s;
for(int i=1;i<=m;i++){
int u,v,w;cin>>u>>v>>w;add(u,v,w);
}
//调用算法
dijkstra();
//输出答案
for(int i=1;i<=n;i++) cout<