# 1. Title

As the head of the city's emergency response team, you have a special national map.The map shows several scattered cities and some expressways connecting them.The number of rescue teams in each city and the length of each expressway connecting the two cities are shown on the map.When there are emergency calls to you from other cities, your task is to lead your rescue team to the site as soon as possible, and to assemble as many rescue teams as possible along the way.

### Input format:

The first line of input gives four positive integers N, M, S, D, where N (2 < N < 500) is the number of cities, which by the way assumes the city number is 0 ~ (N_1); M is the number of express roads; S is the city number of the origin; D is the city number of the destination.

The second line gives N positive integers, where the number i is the number of rescue teams in the ith city, separated by spaces.Subsequently, in line M, each row gives information about a freeway: City 1, City 2, the length of the freeway, separated by a space, and the numbers are integers and no more than 500.Input ensures that rescue is feasible and the optimal solution is unique.

### Output format:

The first line outputs the number of shortest paths and the maximum number of rescue teams that can be called.The second line outputs the city number that passes through the path from S to D.Numbers are separated by spaces, and no extra spaces are allowed at the end of the output.

### Input sample:

4 5 0 3 20 30 40 10 0 1 1 1 3 2 0 3 3 0 2 2 2 3 2

### Output sample:

2 60 0 1 3

# 2. Topic Analysis

1. The root cause of this problem is the single-source shortest path, so the basic solution is the Dijkstra algorithm, only to make some changes on the basis of the algorithm implementation.

2. Note the comments in the code that node 0 will participate in the first iteration

3. Use of the fill() function (reference) https://blog.csdn.net/DZT2727/article/details/78314367)

#include <iostream> using namespace std; int main() { int a[10]; fill(a,a+10,20);//Three parameters, the first two are addresses, and the last is the fill value for(int i = 0;i<10;i++) cout <<a[i] << " " ; cout << endl; fill_n(a,5,-3);//Three parameters, first address, second number, and last fill value for(int i = 0;i<10;i++) cout <<a[i] << " " ; cout << endl; return 0; }

Note: The fill_n function cannot be called on empty containers without elements

_Theoretically, because memset() is assigned in bytes, an int array can only be assigned 0 (all 0 at the binary level) or -1 (all 1 at the binary level).

# 3. Code

#include<iostream> #include<stack> using namespace std; #define max 501 #define inf 0xffffff int edges[max][max];//chart int visited[max];//Is Node Accessed int citysaver[max];//Number of rescue teams in the city int savercount[max];//Total number of rescue teams int path[max];//The city's route int pathcount[max];//Number of shortest paths int dist[max]; void Dijkstra(int s,int n) { //fill(dist, dist + 510, inf);/ dist[s] = 0; //visited[s] = 1; path[s] = -1; pathcount[s] = 1; savercount[s] = citysaver[s]; //Initialization of arrays before starting loop for (int i = 1; i < n; i++)//Note that assignment starts at 1 and the length of node 0 is set to 0 { dist[i] = edges[s][i]; } for (int i = 0; i < n; i++) { int u=-1, min = inf; for (int j = 0; j < n; j++) { //Because the following not only optimizes the distance, but also updates the number of rescue teams, routes and other information, if you directly let u start from the next node 1 nearest to the zero node. //Distance is updatable, but savercount and pathcount of node 1 are unknown, so the task cannot be completed //You can only let u start at 0, first assign savercount and pathcount of 1, so dist[0] is set to 0 if (/*dist[j] != 0 &&*/ dist[j] != inf&&visited[j] == 0) { if (visited[j] == 0&&dist[j] < min) { min = dist[j]; u = j; } } } if (u == -1)return; visited[u] = 1; for (int j = 0; j < n; j++) { if (dist[u] + edges[u][j] < dist[j]&&visited[j]==0&&edges[u][j]!=inf) { dist[j] = dist[u] + edges[u][j]; pathcount[j] = pathcount[u]; savercount[j] = savercount[u] + citysaver[j]; path[j] = u; } else if (dist[u] + edges[u][j] == dist[j] && visited[j] == 0 && edges[u][j] != inf) { pathcount[j] += pathcount[u]; if (savercount[u] + citysaver[j] > savercount[j]) { savercount[j] = savercount[u] + citysaver[j]; path[j] = u; } } } } } int main() { int n, m, s, d; cin >> n >> m >> s >> d; for (int i = 0; i < max; i++) for (int j = 0; j < max; j++) //if (i != j) edges[i][j] = inf; //else edges[i][j] = 0; for (int i = 0; i < n; i++) cin >> citysaver[i]; for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; edges[a][b] = edges[b][a] = c; } Dijkstra(s,n); cout << pathcount[d] << " " << savercount[d] << endl; stack<int>ss; ss.push(d); while (path[d] != 0) { ss.push(path[d]); d = path[d]; } cout << s; while (!ss.empty()) { cout << " " << ss.top(); ss.pop(); } cout << endl; }