zoj 1456
来源:互联网 发布:删失数据如何处理 编辑:程序博客网 时间:2024/06/05 04:09
/*zoj_1456 最短路floyd+路径保存及排序floyd没有太大的问题,关键在于路径的字典序。以前习惯用的路径保存方法:http://blog.csdn.net/xsbailong/article/details/6864437但是这道题这样保存的话找到字典序小的很不容易。这题学到了一种新的保存方法,path[i][j]保存i到j这条路径上i的后继。*/#include <iostream>#include <cstdio>#include <limits.h>#define inf 100000000using namespace std;int map[110][110];int path[110][110];int dist[110][110][110];int city[110];void floyd( int n ){ int i,j,k; for( i=1;i<=n;i++ ) for( j=1;j<=n;j++ ) { if( map[i][j]==-1 ) dist[i][j][0]=inf; else dist[i][j][0]=map[i][j]; } for( k=1;k<=n;k++ ) for( i=1;i<=n;i++ ) for( j=1;j<=n;j++ ) { dist[i][j][k]=dist[i][j][k-1]; if( dist[i][j][k]>dist[i][k][k-1]+dist[k][j][k-1]+city[k] ) { dist[i][j][k]=dist[i][k][k-1]+dist[k][j][k-1]+city[k]; path[i][j]=path[i][k]; } else if( dist[i][j][k]==dist[i][k][k-1]+dist[k][j][k-1]+city[k] ) { if( path[i][j]>path[i][k] ) path[i][j]=path[i][k]; } }}int main(){ int n,i,j,from,to; while( scanf( "%d",&n ) && n ) { for( i=1;i<=n;i++ ) for( j=1;j<=n;j++ ) scanf( "%d",&map[i][j] ),path[i][j]=j; for( i=1;i<=n;i++ ) scanf( "%d",&city[i] ); floyd( n ); while( scanf( "%d%d",&from,&to ) && !( from==-1 && to==-1 ) ) { printf( "From %d to %d :\n",from,to ); printf( "Path: %d",from ); i=from; while( i!=to ) { printf( "-->%d",path[i][to] ); i=path[i][to]; } printf( "\nTotal cost : %d\n\n",dist[from][to][n] ); } } return 0;}