Solving the shortest path (Dijkstra algorithm)

1. Description of the problem (question from PAT A 1003Emergency)

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, C​1​​ and C​2​​ - 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 c​1​​, c​2​​ 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 C​1​​ to C​2​​.

Output Specification:
For each test case, print in one line two numbers: the number of different shortest paths between C​1​​ and C​2​​, 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

The title probably means:

Gives N cities, M article undirected edges. Every city has a number of rescue teams, while the right side of all known, now given the beginning and end, from start to finish seeking the shortest path bar number, and the number of rescue teams on the shortest path and, if there are multiple then the number of shortest paths largest sum output

Sample explained: As shown below, the brackets each point is a point in the right, the right edge is marked with each side, the shortest path from v0 to v2 is 2, a total of two: v0-> v2 and v0-> v1-> v2, and the point on the right of the two paths 2 and 4 are selected so larger

2. The idea of ​​analysis:

① analysis of the topic that we can know the core subject or the shortest path, so we can use Dijkstra's algorithm to solve the shortest path, but before the use of pure different Dijkstra's algorithm is prior knowledge to solve from the source to the rest of the shortest path vertices but here changed a little, it is the shortest route possible and more, and can increase an additional condition is the need to solve a number of vertices of the largest piece of the shortest path shortest path on the right point, which is a variant of the algorithm Dijskstra

② solve the shortest path maximum point Right and we can declare an array w [], meaning w array represents the maximum weight of the point can be obtained from the source s to v and, initially 0, because of the need to solve the shortest path number of pieces we need to declare a further array num, meaning num array representation is the shortest path number vertex u from the source point s, initialization of the sum num [s] = 1 remainder num [V] to 0 , then you need to update the two arrays in updating d [v] when

③ before solving the shortest path to the source vertex of the remaining process is very similar, except that the two arrays to increase the recording correlation values ​​we need to solve, and then add a judgment to see whether the current in the loop can be such that the intermediate node u v s is the distance from the apex are equal, then equal, to the minimum number of updates arrive NUM [v] path, and determines whether or not the right point increases, so if more updates W [v] of the right point

④ so we solved the above problems, the core or Dijkstra algorithm then plus some array to assist to solve

3. The specific code as follows:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm> 
using namespace std;
const int maxSize = 510;
const int INF = 1000000000;
int n, m, st, ed, G[maxSize][maxSize], weight[maxSize];
int d[maxSize], w[maxSize], num[maxSize];
bool vis[maxSize] = {false};
int pre[maxSize];
void Dijstra(int s){
	fill(d, d + maxSize, INF);
	memset(num, 0, sizeof(num));
	memset(w, 0, sizeof(w));
	d[s] = 0;
	w[s] = weight[s];
	num[s] = 1;
	for(int i = 0; i < n; i++){
		int u = -1, min = INF;
		for(int j = 0; j < n; j++){
			if(vis[j] == false && d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++){
			if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
				d[v] = d[u] + G[u][v];
				w[v] = w[u] + weight[v];
				num[v] = num[u];	
			}else if(d[u] + G[u][v] == d[v]){
				if(w[u] + weight[v] > w[v]){
					w[v] = w[u] + weight[v];
				}
				num[v] += num[u];
			}
		}
	}	
}

int main(void){
	cin >> n >> m >> st >> ed;
	for(int i = 0; i < n; ++i){
		cin >> weight[i];
	}
	int u, v, t;
	fill(G[0], G[0] + maxSize * maxSize, INF);
	for(int i = 0; i < m; i++){
		cin >> u >> v >> t;
		G[u][v] = G[v][u] = t; 
	}
	Dijstra(st);
	cout << num[ed] << " " << w[ed];
}

 

 

Guess you like

Origin blog.csdn.net/qq_39445165/article/details/93225217