#include <bits/stdc++.h> #define int long long //(有超时风险) #define PII pair<int,int> #define endl '\n' #define LL __int128 using namespace std; const int N=2e6+10,M=2e3+10,mod=998244353,INF=0x3f3f3f3f; int h[N],e[N],ne[N],w[N],idx; void add(int a,int b,int c) { w[idx]=c;e[idx]=b;ne[idx]=h[a];h[a]=idx++; } bool st[M]; int dist[M],cnt[M]; int way[M],mxsum[M];//分别表示最短路径的数量,救援队最多的数量 int pre[M]; void dij(int beg,int ed) { priority_queue<PII,vector<PII>,greater<PII>>q; q.push({0,beg}); memset(dist,0x3f,sizeof dist); dist[beg]=0; pre[beg]=-1; way[beg]=1; mxsum[beg]=cnt[beg]; while(q.size()) { PII t=q.top();q.pop(); int ver=t.second; int distance=t.first; if(st[ver])continue; st[ver]=true; for(int i=h[ver];~i;i=ne[i]) { int j=e[i]; if(dist[j]>dist[ver]+w[i]) { dist[j]=dist[ver]+w[i]; q.push({dist[j],j});//执行最短路 //记录附加信息 way[j]=way[ver]; mxsum[j]=mxsum[ver]+cnt[j]; pre[j]=ver; } else if(dist[j]==dist[ver]+w[i]) { //记录附加信息 way[j]+=way[ver]; if(mxsum[j]<mxsum[ver]+cnt[j]) { mxsum[j]=mxsum[ver]+cnt[j]; pre[j]=ver; } } } } } signed main() { int n,m,st,ed;cin>>n>>m>>st>>ed; for(int i=0;i<n;i++)cin>>cnt[i]; memset(h,-1,sizeof h); for(int i=1;i<=m;i++) { int x,y,z;cin>>x>>y>>z; add(x,y,z); add(y,x,z); } dij(st,ed); cout<<way[ed]<<' '<<mxsum[ed]<<endl; //要前往后记录信息,pre数组表示当前点的上一个点是什么; //所以用栈 stack<int>q; while(pre[ed]!=-1) { q.push(ed); ed=pre[ed]; } //要输出出起始点; cout<<st; while(q.size()) { cout<<' '<<q.top(); q.pop(); } return 0; }
L2-001 紧急救援
最新推荐文章于 2025-08-07 23:09:33 发布