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;}