Topic link: https://www.patest.cn/contests/pat-a-practise/1003
The meaning of the question, give us n points, there are m roads, each point has a weight, each road has its own length and is a two-way road, let us find the distance from the starting point s to the end point e The number of shortest paths, and find the weights of all points and the largest one in these shortest paths.
After careful analysis, this problem should be a deformation problem of the shortest path (if students who are not proficient in the shortest path can go out and turn left to learn the shortest path: the portal ), it is very easy to first find the weight and the largest one, just need to It is easier to add a weight sum to the path length as a second comparison condition.
Then the key question is how to find the shortest path number. The method used by the editor here is to use a num array to record the number of shortest paths from s to the current point. When we update the shortest path, if the path from the previous point a to the current point b is shorter than the current path to b, Then num[b] = num[a], if the path from a to b is equal to the shortest path to the current b, then num[b] += num[a], after each update, clear the num of the previous point Zero to avoid repeated updates.
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 505; int mp[maxn][maxn]; int num[maxn], dis[maxn], sum[maxn]; int val[maxn]; int s, e, n; struct Edge{ int v, w, next; }edge[maxn*maxn]; int head[maxn], tot; void init() { to = 0; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int w) { edge[tot].v = v; edge [tot] .w = w; edge[tot].next = head[u]; head[u] = tot++; } void SPFA() { queue<int> q; q.push(s); memset(num,0,sizeof(num)); memset(dis,INF,sizeof(dis)); memset(sum,0,sizeof(sum)); dis[s] = 0; sum[s] = val[s]; num[s] = 1; int u,v,w; while(!q.empty()) { u = q.front(); q.pop(); if(u == e) continue; for(int i=head[u]; i!=-1; i=edge[i].next) { v = edge [i] .v; w = edge[i].w; if(dis[v] > dis[u]+w) { dis[v] = dis[u]+w; sum [v] = sum [u] + val [v]; if(!num[v]) q.push(v); num[v] = num[u]; } else if(dis[v] == dis[u]+w) { sum [v] = max (sum [u] + val [v], sum [v]); if(!num[v]) q.push(v); num[v] += num[u]; } } num [u] = 0; } } intmain() { int m, u, v, w; scanf("%d%d%d%d",&n, &m, &s, &e); init(); for(int i = 0; i < n; ++i) { scanf("%d",&val[i]); } memset(mp,INF,sizeof(mp)); while(m--) { scanf("%d%d%d",&u, &v, &w); addEdge(u, v, w); addEdge(v, u, w); } SPFA(); printf("%d %d\n",num[e], sum[e]); return 0; }