这是本小学生地一次发题解,建议丝滑连招。
这题就是一个带权无向图,求节点1到节点v的最短路,输出路径即可。题目保证不出现负边。
由于数据范围到了2e5。只好用dijkstra。可dijkstra只能求起点到所有点的最短路。1到v的最短路可以求了,如何求路径呢??这里有一个路径还原的方法,就是记录每个节点到一的最短路中,此节点的前一个结点。求好后写一个循环,每次去他的前一个结点,到一路径还原就完成了。
本体重点!!!
1.不开longlong见祖宗!!!
2.v很大,存边权别用数组!!!
以下是c++实现
#include <bits/stdc++.h>
#define ll long long
#define MP make_pair
#define G_(v) vector<int> a[v]
#define pa pair<ll,ll>
#define MP make_pair
#define dijk priority_queue
const int N=2e5+1;
using namespace std;
ll v,e,lx,ly,lz,d[N],nt[N];
vector<int> ans;
G_(N);//a:x,y,z
map<ll,map<ll,ll> > cost;// a-b c
void dijkstra(){
memset(d,0x3f,sizeof(d));
d[1]=0,nt[0]=-1;
dijk<pa, vector<pa>, greater<pa> > w;
w.push(MP(0,1));
while(!w.empty()){
pa x=w.top();w.pop();
ll rt=x.second;
if(d[x.second]>=x.first)
for(int i=0;i<a[rt].size();i++)
if(d[rt]+cost[rt][a[rt][i]]<d[a[rt][i]]){
d[a[rt][i]]=d[rt]+cost[rt][a[rt][i]];
nt[a[rt][i]]=rt;
w.push(MP(d[a[rt][i]],a[rt][i]));
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie();
cin>>v>>e;
for(int i=0;i<e;i++){
cin>>lx>>ly>>lz;
a[lx].push_back(ly);
a[ly].push_back(lx);
cost[lx][ly]=cost[ly][lx]=lz;
}
dijkstra();
if(d[v]<1e18){
while(v!=1){
ans.push_back(v);
v=nt[v];
}
ans.push_back(1);
reverse(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" ";
}
else cout<<-1;
return 0;
}