#include <bits/stdc++.h>
using namespace std;
const int N=11111;
int n,m,s,d;
typedef pair<int,int>PII;
int a[N],res[N];
int h[N],ne[N],e[N],w[N],idx;
int dist[N];
bool st[N];
int path[N],way[N],du[N]; // path 记录位置点,way 记录道路条数,du记录该点权值
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dijk()
{
dist[s]=0;
priority_queue<PII,vector<PII>,greater<PII> > q;
q.push({0,s});
while(q.size())
{
PII t=q.top();
q.pop();
int ver=t.second,distance=t.first;
if(st[ver]) continue;
st[ver]=1;
for(int i=h[ver];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>distance+w[i])
{
dist[j]=distance+w[i];
q.push({dist[j],j});
way[j]=way[ver];
du[j]=du[ver]+a[j];
path[j]=ver;// 到点j的最短路径中 上一个点
}
else if(dist[j]==distance+w[i])
{
way[j]+=way[ver];
if(du[j]<du[ver]+a[j])
{
du[j]=du[ver]+a[j];
path[j]=ver;
}
}
}
}
}
int main()
{
cin>>n>>m>>s>>d;
memset(h,-1,sizeof h);
memset(dist,0x3f3f,sizeof dist);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
du[s]=a[s];
way[s]=1;
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
dijk();
cout<<way[d]<<" "<<du[d]<<endl;
int l=0;
res[l++]=d;
while(1) // 由于每次都存储的该地点的上一个点,所以要倒序找路径
{
res[l++]=path[d];
if(path[d]==s)// 当找到起始点便可以停止了
break;
d=path[d];
}
for(int i=l-1;i>=0;i--)
{
if(i==0)
cout<<res[i]<<endl;
else
cout<<res[i]<<" ";
}
return 0;
}
L2-001 紧急救援 (25 分)(优化版dijkstra+路径存储)
最新推荐文章于 2024-04-27 15:25:53 发布