Tourism planning (25 points) (Dijkstra)

With a self-driving tour route map, you will know the length of the highway between cities and the tolls to be charged for the highway. Now you need to write a program to help tourists who come to consult to find the shortest path between the starting point and the destination. If there are several paths that are the shortest, then the cheapest path needs to be output.
Input format:
Input description: The first line of the input data gives 4 positive integers N, M, S, D, where N (2≤N≤500) is the number of cities. By the way, assume that the number of the city is 0~( N-1); M is the number of expressways; S is the city number of the departure place; D is the city number of the destination. In the subsequent M lines, each line gives information about a highway, which are: city 1, city 2, highway length, and toll amount, separated by spaces, and the numbers are all integers and do not exceed 500. The input guarantees the existence of the solution.

Output format:
output the length of the path and the total charge in one line. The numbers are separated by spaces, and there should be no extra spaces at the end of the output.

Input sample:

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

Sample output:

3 40

Question ideas:
1. I solved the problem by referring to the explanation of the Dijkstra algorithm in the book of "Algorithm Notes" by Mr. Hu Fan. The last three test points on the pta were always wrong, and later I found that it was the process of building the map. It is a directed graph, because it should be a two-way process.
2. This question is the Dijkstra algorithm with side weights, which is a flexible application based on the Dijkstra algorithm.
3. Regarding the Dijkstra algorithm, my personal understanding is to traverse n vertices, find the vertex with the smallest weight each time, and then use that vertex as an intermediary to find the next shortest edge, and use the d array to record it.

#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f;
int n, m, s, ter, Graph[MAXN][MAXN];	
int d[MAXN];		//当前顶点到起点的最短路径长度
int c[MAXN];		//当前顶点到起点的花费
int cost[MAXN][MAXN];	//两个顶点间的花费
bool Visited[MAXN];	//访问标志数组
void Dijkstra(int s);
int main()
{
    
    
	fill(Graph[0], Graph[0] + MAXN * MAXN, INF);
	fill(cost[0], cost[0] + MAXN * MAXN, INF);		//初始化
	int u, v, w, x;
	cin >> n >> m >> s >> ter;
	while (m--)							//建图
	{
    
    
		cin >> u >> v >> w >> x;
		Graph[u][v] = Graph[v][u] = w;		//记住这道题问的是无向图,建立的时候是双向的
		cost[u][v] = cost[v][u] = x;
	}

	Dijkstra(s);			
		
	cout << d[ter] << " " << c[ter];	//输出terminal顶点到起点的最短路径长度和最少花费

	return 0;
}
void Dijkstra(int s)
{
    
    
	fill(d, d + MAXN, INF);
	fill(c, c + MAXN, INF);
	d[s] = 0;					
	c[s] = 0;				//以上四条语句均为初始化
	for (int i = 0; i < n; i++)		//循环n次
	{
    
    
		int u = -1, MIN = INF;
		for (int j = 0; j < n; j++)		//查找权值最小的边
			if (!Visited[j] && d[j] < MIN)	//寻找未被访问顶点中最小d[]
			{
    
    
				u = j;
				MIN = d[j];
			}
		if (u == -1) return;		//如果找不到小于INF,说明剩下的点不连通
		Visited[u] = true;			//标记
		for (int v = 0; v < n; v++)		//以找到的u作为连接下一个顶点v的中介点
			if (!Visited[v] && Graph[u][v] != INF)
			{
    
    
				if (d[u] + Graph[u][v] < d[v])	//下一条权值小的边
				{
    
    
					d[v] = d[u] + Graph[u][v];	//更新权值
					c[v] = c[u] + cost[u][v];	//更新费用
				}
				else if (d[u] + Graph[u][v] == d[v] && c[u] + cost[u][v] < c[v])//路径相同,但费用变小则需要更新
					c[v] = c[u] + cost[u][v];
				}
	}
}

Guess you like

Origin blog.csdn.net/xdg15294969271/article/details/114293182