这是一个裸的最短路的模板题,但是它需要输出路径。
用dijkstra的话首先敲一个最短路的板子,其次开一个数组p[]来记录路径,但是怎么存呢?我们需要记录每一个点的前驱,因为如果记录后边的话,一个点可能连多个节点,但是每一个点的前驱只有一个点,所以记录每一个被压入堆的点即可,最后输出。如果用spfa的话,也同理存入被松弛的点。
1.一定要注意数据类型,long long 足以让你死掉,当然也要全部修改,注意全局这个变量的出现都要修改。
2.注意加边的时候是有向边还是无向边。
3.记录路径一定是p[i]=j代表从j->i的路径,所以输出要倒序。
代码
#include<bits/stdc++.h> #define maxn 500005 #define maxm 500005 using namespace std; struct edge{ int next; long long w; int v; }e[maxm]; int n,m,tot=0,s; int head[maxn],vis[maxn],pos[maxn]; long long dis[maxn]; struct node{ long long w; int now; inline bool operator <(const node &x)const { return w>x.w;//这里注意符号要为'>' } }; inline void add(int u,int v,long long w){ e[++tot].next=head[u]; head[u]=tot; e[tot].w=w; e[tot].v=v; } priority_queue<node>q; void dijkstra(){ for(int i=1;i<=n;i++) { dis[i]=9223372036854775806; } dis[1]=0; q.push((node){0,1}); while(!q.empty()){ node x=q.top(); int u=x.now; q.pop(); if(vis[u]==1) continue; vis[u]=1; for(int i=head[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}); pos[e[i].v]=u; } } } } int main(){ cin>>n>>m; for(int i=1,x,y,z;i<=m;i++){ cin>>x>>y>>z; add(x,y,z); add(y,x,z); } dijkstra(); bool flag=false; int num=0; int ans[maxn]; for(int i=n;i;i=pos[i]){ ans[++num]=i; if(i==1){ flag=true; } } if(flag==true){ for(int i=num;i>=1;i--){ cout<<ans[i]<<" "; } } else cout<<-1; return 0; }