The cost of the transportation on the path between these cities, and
a certain tax which will be charged whenever any cargo passing through one city, except for the source and the destination cities.
You must write a program to find the route which has the minimum cost.
InputFirst is N, number of cities. N = 0 indicates the end of input.
The data of path cost, city tax, source and destination cities are given in the input, which is of the form:
a11 a12 ... a1N
a21 a22 ... a2N
...............
aN1 aN2 ... aNN
b1 b2 ... bN
c d
e f
...
g h
where aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, ..., and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:
OutputFrom c to d :
Path: c-->c1-->......-->ck-->d
Total cost : ......
......
From e to f :
Path: e-->e1-->..........-->ek-->f
Total cost : ......
Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.
Sample Input
5 0 3 22 -1 4 3 0 5 -1 -1 22 5 0 9 20 -1 -1 9 0 4 4 -1 20 4 0 5 17 8 3 1 1 3 3 5 2 4 -1 -1 0
Sample Output
From 1 to 3 : Path: 1-->5-->4-->3 Total cost : 21 From 3 to 5 : Path: 3-->4-->5 Total cost : 16 From 2 to 4 : Path: 2-->1-->5-->4 Total cost : 17
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<sstream> #include<algorithm> #include<queue> #include<deque> #include<iomanip> #include<vector> #include<cmath> #include<map> #include<stack> #include<set> #include<fstream> #include<memory> #include<list> #include<string> using namespace std; typedef long long LL; typedef unsigned long long ULL; #define MAXN 103 #define L 31 #define INF 1000000009 #define eps 0.00000001 int g[MAXN][MAXN],path[MAXN][MAXN], n, v[MAXN];//path[i][j] 表示路径i->j上 i之后的第一个结点 void Floyd() { for (int k = 1; k <= n; k++) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (g[i][j] > g[i][k] + g[k][j] + v[k]) { g[i][j] = g[i][k] + g[k][j] + v[k]; path[i][j] = path[i][k];//将路径结点缩小范围确定 } else if (g[i][j] == g[i][k] + g[k][j] + v[k]) { if (path[i][j] > path[i][k]) { path[i][j] = path[i][k];//比较前面的字典序 } } } } } } void Print(int u, int v)//递归 从i->j 可以分解为 i->path[i][j]->path[path[i][j]][j]->,,,,,j { if (u == v) { printf("%d ", u); return; } int k = path[u][v]; printf("%d-->", u); Print(k, v); } int main() { while (scanf("%d", &n), n) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &g[i][j]); path[i][j] = j; if (g[i][j] == -1) g[i][j] = INF; } } for (int i = 1; i <= n; i++) scanf("%d", &v[i]); int f, t; Floyd(); while (scanf("%d%d", &f, &t), f != -1 && t != -1) { printf("From %d to %d : Path: ", f, t); Print(f, t); printf("Total cost : %d ", g[f][t]); } } }