//In addition to the weight of the edge, each point also has a weight, so the weight of the point should also be calculated during the relaxation operation.//In
addition, in the case of the minimum total cost, the path with the smallest lexicographical order should be output , which is also processed in the relaxation operation
//If you can update d[i] to make d[i] smaller, update it directly
addition, in the case of the minimum total cost, the path with the smallest lexicographical order should be output , which is also processed in the relaxation operation
//If you can update d[i] to make d[i] smaller, update it directly
//If it is the same as d[i], judge whether the lexicographic order of the path will be smaller if it is updated, if it can be updated, otherwise it will not be updated; this is very similar to the record cost
#include <iostream> #include <memory.h> #include <stdio.h> using namespace std; #define Max_V 1005 const int IN = (1<<28); int G[105][105]; int Path[105][105]; int Tax[105]; int N,S,D; void Floyd() { for( int u = 1; u <= N; u++ ) for( int v = 1; v <= N; v++ ) for( int w = 1; w <= N; w++ ) { if( G[v][w] > G[v][u] + G[u][w] + Tax[u] ) { G[v][w] = G[v][u] + G[u][w]+ Tax[u]; Path[v][w] = Path[v][u]; } else if( G[v][w] == G[v][u] + G[u][w] + Tax[u] ) { if( Path[v][w] > Path[v][u] ) { Path[v][w] = Path[v][u]; } } } } void Print(int i, int j) { if( i==j ) { printf("%d",i); return; } printf("%d-->",i); Print(Path[i][j],j); } intmain() { while( cin >> N, N!=0) { memset(G, 0, sizeof(G)); memset(Path, 0, sizeof(Path)); for( int i = 1; i <= N; i++ ) { for( int j = 1; j <= N; j++ ) { Path[i][j] = j; cin >> G[i][j]; if( G[i][j] == -1 ) { G[i][j] = IN; } } } for( int i = 1; i <= N; i++ ) cin >> Tax[i]; Floyd(); while( cin >> S >> D, S != -1 || D != -1 ) { if( S==D ) { printf("From %d to %d :\n",S,D); printf("Path: %d\n",S); printf("Total cost : %d\n\n", 0); continue; } printf("From %d to %d :\n",S,D); printf("Path: "); Print(S,D); printf("\n"); printf("Total cost : %d\n\n", G[S][D]); } } return 0; }