As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.
Input Specification:
Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C1and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.
Output Specification:
For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.
Sample Input:
5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1
Sample Output:
2 4
Analyse:
It's obvious that we should use Dijkstra algorithm to solve this problem. First it's significant to find the shortest path to every city, which is Dijkstra algorithm's effect. Besides, we must use two arrays ‘team’ and ‘num’ to denote respectively the maxium number of rescue teams you can gather together and the number of shortest path from the start city to current city. When we arrive at a new city, we should refresh the length, the number of teams and the number of shortest path.
If my description is not clearly enough, here's a another analysis: https://www.liuchuo.net/archives/2359
#include<iostream>
#define MAX 0X0FFFFFFF
using namespace std;
int edge[501][501], team[501], visited[501], dis[501], num[501];
int main(){
int N, num_roads, start, finish, index, num_team;
int point1, point2, weight, current;
scanf("%d%d%d%d", &N, &num_roads, &start, &finish);
//Initialize
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
edge[i][j] = MAX;
for(int i = 0; i < N; i++) scanf("%d", &team[i]);
for(int i = 0; i < num_roads; i++){
scanf("%d%d%d", &point1, &point2, &weight);
edge[point1][point2] = weight;
edge[point2][point1] = weight;
}
for(int i = 0; i < N; i++) dis[i] = MAX;
//Find the shorest path
visited[start] = 1;
num[start] = 1;
current = start;
dis[start] = 0;
for(int i = 1; i < N; i++){ //Add the other points to set
int min = MAX;
//Refresh
for(int j = 0; j < N; j++){
if(!visited[j] && edge[current][j] < MAX && dis[current] + edge[current][j] < dis[j]){
dis[j] = dis[current] + edge[current][j];
}
}
//Find the nearest point
for(int j = 0; j < N; j++){
if(!visited[j] && dis[j] < min){
min = dis[j];
index = j;
}
}
//Refresh the team number
num_team = team[index];
for(int j = 0; j < N; j++){
if(visited[j] && team[index] < team[j] + num_team && dis[j] + edge[j][index] == min){
team[index] = team[j] + num_team;
}
}
//Refresh the number of roads
for(int j = 0; j < N; j++){
if(visited[j] && dis[j] + edge[j][index] == min) num[index] += num[j];
}
visited[index] = 1;
current = index;
}
printf("%d %d", num[finish], team[finish]);
return 0;
}
As you can see from the page I paste above, there's a better way to initialize arrays. We can use fill() included in algorithm. If you want to konw more about this function, click it:https://blog.csdn.net/liuchuo/article/details/52296646