方法:
方法就是在進行鬆弛操做的時候,若是能經過某個點進行鬆弛操做,就把這個點的出去的那個點的前驅設置爲這個點node
正確性:
由於全部點都會被至少鬆弛到一次,若是不進行鬆弛操做,那麼這個點的前驅就必定仍是原來的前驅。這個是Dijkstra算法的一個很神奇的地方,若是能進行鬆弛操做,說明若是要經過最短路到達這個點,就只能修改這個點的前驅。ios
模板題目來源:
https://www.luogu.org/problemnew/show/CF20C算法
代碼:
#include <iostream> #include <queue> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; const int N = 1e5+5; const long long INF = 9223372036854775806; int n,m; int vis[N]; int pre[N]; long long dis[N]; struct node{ int u; long long w; }; vector <int> ans; vector <node> graph[N]; priority_queue <pair<long long,long long>,vector <pair<long long,long long> >,greater <pair<long long,long long> > > q; void add(int x,int y,long long z) //雙向圖 { node temp; temp.u=y; temp.w=z; graph[x].push_back(temp); temp.u=x; graph[y].push_back(temp); } void Dijkstra(int x) { while(!q.empty()){ pair <long long,long long> temp; temp=q.top(); q.pop(); if(vis[temp.second]!=0) continue; vis[temp.second]++; vector <node> :: iterator it; for(it=graph[temp.second].begin();it!=graph[temp.second].end();it++) { if(vis[it->u]!=0) continue; if(dis[it->u]>dis[temp.second]+(it->w)) { dis[it->u]=dis[temp.second]+(it->w); pre[it->u]=temp.second; q.push(make_pair(dis[it->u],it->u)); } } } } int main() { scanf("%d%d",&n,&m); int temp_x,temp_y; long long temp_z; for(int i=1;i<=m;i++) { scanf("%d%d%lld",&temp_x,&temp_y,&temp_z); add(temp_x,temp_y,temp_z); } //初始化dis數組 for(int i=1;i<=n;i++) dis[i]=INF; dis[1]=0; q.push(make_pair(dis[1],1)); Dijkstra(1); bool flag=false; int x=n; while(true) { if(x==1) flag=true; ans.push_back(x); x=pre[x]; if(x==0) break; } if(!flag) printf("-1\n"); else { for(int i=(int)ans.size()-1;i>=0;i--) printf("%d ",ans[i]); printf("\n"); } return 0; }