题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805073643683840
题目大意:就是让你找一个单源最短路,同时还需要能够输出最短路的路径
输入:
第一行n,m,s,d,分别是城市数,路径数,起点,终点。
第二行n个数,是每个城市有的救援队的数目
接下来m行就是每条道路的两个端点和长度
输出:
第一行输出最短路径条数和救援队数量,第二行就是从起点到终点的路径。
分析:本质上还是用dij做的最短路问题,但需要添加些东西,我们可以用num数组表示从起点到i的最短路径条数,w数组表示救援队数量
同时最用dij做最短路的时候,把最短路径上每个城市的前驱用pre数组记录下来
这样,在更新最短路时,如果dis[e.to]>dis[v]+e.cost 就需要将v和e.to连接起来,那么num[e.to]就应该和num[v]保持一致,w[e.to]=w[v]+a[e.to]
除了大于的情况,对于dis[e.to]==dis[v]+e.cost,我们也需要考虑,因为e.to的最短路径条数除了本身的,还有从v连接过来的,则num[e.to]+=num[v]
如果w[v]+a[e.to]>w[e.to],那么w[e.to]=w[v]+a[e.to],因为要保证救援队数量最多
另外每当连路径的时候记得把pre数组录入一下,最后递归输出即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=1<<30; 4 typedef long long ll; 5 typedef pair<int,int> P; 6 const double pi=acos(-1); 7 const int mod=1e8+7; 8 const int maxn=505; 9 const int maxm=6300; 10 int dis[maxn]; 11 int a[maxn],num[maxn],w[maxn],pre[maxn];//num数组是出发点到i点时拥有的路径的条数,w数组是救援队的数目 12 struct edge{ 13 int to,cost; 14 }; 15 int x,y,z,n,m,s,d; 16 vector<edge> g[maxm]; 17 void dij(int s){ 18 priority_queue<P,vector<P>,greater<P> > que; 19 fill(dis,dis+maxn,inf); 20 dis[s]=0; 21 w[s]=a[s],num[s]=1;//初始化,到起始点救援队数量就是起始点本身救援队数量,路径也只有一条 22 que.push({0,s}); 23 while(!que.empty()){ 24 P p=que.top();que.pop(); 25 int v=p.second; 26 if(dis[v]<p.first) continue; 27 for(int i=0;i<g[v].size();i++){ 28 edge e=g[v][i]; 29 if(dis[e.to]>dis[v]+e.cost){//这种情况肯定要从v到e.to了 30 num[e.to]=num[v]; 31 w[e.to]=w[v]+a[e.to]; 32 dis[e.to]=dis[v]+e.cost; 33 pre[e.to]=v; 34 que.push({dis[e.to],e.to}); 35 } 36 else if(dis[e.to]==dis[v]+e.cost){ 37 if(w[v]+a[e.to]>w[e.to]){w[e.to]=w[v]+a[e.to];pre[e.to]=v;} 38 num[e.to]+=num[v]; //还要再加上v点的 39 } 40 } 41 } 42 } 43 void print(int c){ 44 if(c==s){ 45 cout<<s;return; 46 } 47 print(pre[c]); 48 cout<<" "<<c; 49 } 50 int main(){ 51 scanf("%d%d%d%d",&n,&m,&s,&d); 52 for(int i=0;i<n;i++) scanf("%d",&a[i]); 53 for(int i=0;i<m;i++){ 54 scanf("%d%d%d",&x,&y,&z); 55 g[x].push_back({y,z}); 56 g[y].push_back({x,z}); 57 } 58 dij(s); 59 cout<<num[d]<<" "<<w[d]<<endl; 60 print(d); 61 cout<<endl; 62 return 0; 63 }