The original question is as follows:

A Traveler ' s map gives the distances between cities along the highways, together with the cost of each highway. Now is supposed to write a program to help a traveler to decide the shortest path between his/her starting city and T He destination. If such a shortest path is isn't unique, you were supposed to the output of the one with the minimum cost, which was guaranteed to be Unique.

**Input Specification:**

Each input file contains the one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (<=500) are the number of cities (an D Hence the cities is numbered from 0 to N-1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M. lines follow, each provides the information of a highway, in the format:

City1 City2 Distance Cost

Where the numbers is all integers no more than, and is separated by a space.

**Output Specification:**

For each test case, print in one line the cities along the shortest path from the starting point to the destination, Follo Wed by the total distance and the total cost of the path. The numbers must is separated by a space and there must is no extra space at the end of output.

**Sample Input**
4 5 0 30 1 1 201 3 2 300 3 4 100 2 2 202 3 1 20

**Sample Output**
0 2 3) 3 40

The topic asks for a graph to find out all the shortest distances between source and node, and to filter out an optimal path for the second weight (cost).

To achieve the single-source shortest path algorithm, using Dijkstra can, but also for multiple results according to the path filter, only need to dijkstra a small variant.

This problem I completely refer to the solution of Sunbaigui, below I will briefly introduce this solution .

① in order to record the path, each city is defined as a node:

typedef struct NODE{INT dis, cost, path; Node () {dis=inf; cost=inf; path=-1;}} Node;

we know that Dijkstra needs an array mindist record the shortest distance from the source point to each point, and we also need a mincost record the minimum cost from the source point to the current point to determine if the path should be updated when the path is long. Using node nodes, the cost and dis represent the costs and distances of the source point to the current point, and path is used to record the precursor node, 1 means no precursor, that is, the source point, which makes it convenient to store multiple quantities.

Put node in the container vector to record all the nodes in the entire map.

② charts with Edge storage:

typedef struct EDGE{INT end, dis, cost; Edge (int e, int d, int c) {end = e; dis = d; cost = C;}};

The edge is placed in the container vector, and each edge represents the dis, cost from the index of the current edge to the end.

Another way to ③dijkstra:

First of all, the traditional Dijkstra we will update the source point of the adjacency point of the mindist as the source point to this point of distance, convenient for the back of the search, and this algorithm is to integrate this operation into the Dijkstra algorithm, the implementation principle of first initialized to the source point of the distance of 0, But does not join the collection , so that in the first scan will find the source point, and then update all the neighboring points for the source point, so that the write avoids the redundant initialization operation, the implementation of the unity of operation, very ingenious.

Second, when the path is found to be equal, it is necessary to compare the cost of the intermediate point to the adjacency point less than the original, if less also to update, the way to update the path is to set the precursor node as an intermediate point.

Backtracking of ④ paths:

Through the Dijkstra algorithm, we can go backwards through the path of the endpoint until we find 1, which is the source point, pressing the node in the backtracking process into a stack and then using the stack output to print the path in a positive order.

The code is as follows:

#include <algorithm> #include <iostream> #include <vector> #include <stack> #include < stdio.h>using namespace std; #define INF 0x6fffffff//city nodes, each node records the minimum cost and shortest path to reach the city, which can be traced back to the source point through a series of city nodes. typedef struct NODE{INT dis, cost, path; Node () {dis=inf; cost=inf; path=-1;}} node;//each edge records the path information from an Edge array index to an end member of an edge typedef struct EDGE{INT end, dis, cost; Edge (int e, int d, int c) {end = e; dis = d; cost = C;}}; int N, m, S, t;vector<vector<edge> > Edge; Save the whole picture by the edge structure vector<int> path;vector<node> city; All city nodes Vector<bool> visited; The access tag used for Dijkstra, some books will visited understood as set, that is, the node is added to the collection, both to prevent nodes from being repeatedly accessed. The shortest path search for int findmin ()///Dijkstra, where city functions equal to the mindist array, I index represents the shortest distance from the source point to I. {int mmin = Inf;int k = -1;for (int i = 0; i < n; ++i) {if (!visited[i] && City[i].dis < mmin) {mmin = City[i]. Dis;k = i;}} return k;} void Dijkstra (int s, int t) {visited.assign (n, false); City.clear (); City.resize (n);//According to the construction method, the initial distance to each city node is INF, Each node has no precursor node (-1). City[s].dis = 0;City[s].cost = 0; The distance initialized to the source point is 0, and the 0.//regular Dijkstra is the first to initialize all the distances to the source point, but not here. His principle is that the source point is not added to the collection, but in the first round of the loop to get the source point (because only to the source point is not the INF)//and then realize all the initialization to the source point, the implementation of the unity of operation, very ingenious. while (true) {int u = findmin (); if (U = =-1) return;visited[u] = true;//find the shortest path from the source to each point and not access the point U, set to access, and update all adjacency points for U. for (int i = 0; i < edge[u].size (); ++i) {int v = edge[u][i].end;//V is an adjacency point of u int cost = Edge[u][i].cost;//Cost is u to this adjacency The distance of point v int dis = Edge[u][i].dis; The dis is the distance to u to this adjacency point v if (!visited[v]) {if (City[v].dis > City[u].dis+dis)////If the distances through the middle point U reach v are shortened, the path should be updated to reach v via U. {city[v].dis= City[u].dis+dis;city[v].cost = City[u].cost+cost;city[v].path = u;} else if (City[v].dis = = City[u].dis+dis//If the distance is not changed, but the cost is reduced, still need to update && city[v].cost > City[u].cost+cost) {city[v]. Cost = City[u].cost+cost;city[v].path = U;}}}} void OutputPath (int t) {//From the end point back to the source point, the flag to the source point is path=-1//a stack implementation to traverse forward output stack<int> Ans;ans.push (t), while (City[t]. Path! =-1) {t = City[t].path;ans.push (t);} while (!ans.empty ()) {printf ("%d", ans.top ()); Ans.pop ();}} int main () {while (scanf ("%d%d%d%d", &n,&m,&s,&t)!=eof) {edge.clear (); Edge.resize (n); and while (m--) {int u, V, D, C; scanf ("%d%d%d%d", &u,&v,&d,&c), Edge[u].push_back (Edge (V, D, c)), Edge[v].push_back (Edge (U, D, c));} Dijkstradijkstra (S, t); OutputPath (t);p rintf ("%d%d\n", City[t].dis, City[t].cost);} return 0;}

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

1030. Travel Plan (30)