You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int INF = 0x3f3f3f3f ;
const int N = 1003 ;
int g [ N ] [ N ] ; // 邻接矩阵
int n ; // n个点
int w [ N ] ; // 额外费用
int path [ N ] [ N ] ; // 路径
void floyd ( ) {
for ( int k = 1 ; k < = n ; k + + )
for ( int i = 1 ; i < = n ; i + + )
if ( g [ i ] [ k ] ! = INF ) // floyd优化
for ( int j = 1 ; j < = n ; j + + ) {
if ( g [ i ] [ j ] > g [ i ] [ k ] + g [ k ] [ j ] + w [ k ] ) { // w[k]:点权
g [ i ] [ j ] = g [ i ] [ k ] + g [ k ] [ j ] + w [ k ] ; // k的加入, 使得i->j的路径变短
path [ i ] [ j ] = path [ i ] [ k ] ;
}
if ( g [ i ] [ j ] = = g [ i ] [ k ] + g [ k ] [ j ] + w [ k ] ) { // 如果存在多条最短路径, 也就是, 除了k还有其它k1,k2使得i->j距离一样小
if ( path [ i ] [ j ] > path [ i ] [ k ] ) path [ i ] [ j ] = path [ i ] [ k ] ; // 字典序,谁更小就留下谁
}
}
}
int main ( ) {
while ( cin > > n & & n ) {
for ( int i = 1 ; i < = n ; i + + ) {
for ( int j = 1 ; j < = n ; j + + ) {
path [ i ] [ j ] = j ; // 路径初始化,记录整条路径上, 离i节点最近的, 最短路径上的下一个点, 只有i->j时, 下一个点可不就是j
cin > > g [ i ] [ j ] ;
if ( g [ i ] [ j ] = = - 1 ) g [ i ] [ j ] = INF ;
}
}
for ( int i = 1 ; i < = n ; i + + ) cin > > w [ i ] ; // 读入点权
// 多源最短路径
floyd ( ) ;
// 处理询问
int x , y ;
while ( cin > > x > > y ) {
if ( x = = - 1 & & y = = - 1 ) break ;
printf ( " From %d to %d : \n " , x , y ) ;
printf ( " Path: %d " , x ) ;
int u = x , v = y ;
// 理解路径思路:
// (1) 从起点x出发,用循环打印路径,最后一个打印的肯定是y
// (2) 从起点x出发,第二个点应该是离x最近的, 并且是最短路径上的那个点,这个点就是path[x][y]!
// path[x][y]: 从起点x出发, 到终点y有多条最短路径, 我们选择字典序最小的那条最短路径, 然后path[x][y]就是从x出发, 离x最近的这条最短路径上的点。
while ( x ! = y ) {
printf ( " -->%d " , path [ x ] [ y ] ) ; // 输出距离x最近的那个点
x = path [ x ] [ y ] ; // 更换x概念, 向y逼近, 让循环跑起来
}
puts ( " " ) ;
if ( g [ u ] [ v ] < INF )
printf ( " Total cost : %d \n " , g [ u ] [ v ] ) ;
else
puts ( " -1 " ) ;
puts ( " " ) ;
}
}
return 0 ;
}