ZOJ 1456 / HDOJ 1385 -- Minimum Transport Cost (FLoyd+路径字典序)

之前尝试用 Dijkstra 写,但是回溯部分不会写,无奈之下网上找了一下别人的解题报告,发现竟然是用 Floyd 写的,我接触 Floyd 不太深入,于是在做这道题目的时候,我重新回顾了 Floyd 算法,思考其核心思想

 

预处理:约定 edge 保存输入数据的边权值,tax 保存站点的费用,ss,tt 分别记录当前的 起点 和 终点,那么可以这样构图,对于 ss 和 tt,显然这两点是不需要 tax 的,那么dist 数据记录 ss 到 当前点 k 的总费用,即 dist[ i ][ j ] = edge[ i ][ j ] + tax[ j ] (edge[ i ][ j ]!=0,edge[ i ][ j ]!=INF,j!=ss,j!=tt)

 

代码如下:

View Code
  1 /*

  2 PROG:   Minimum Transport Cost

  3 ID  :   ouyangyewei

  4 LANG:   C++

  5 */

  6 #include <cstdio>

  7 #include <cstdlib>

  8 #include <cstring>

  9 #include <memory.h>

 10 #include <algorithm>

 11 

 12 const int maxn = 36;

 13 const int INF = 0x3F3F3F3F;

 14 

 15 int  N, EndPoint, tax[maxn], edge[maxn][maxn];

 16 int  path[maxn][maxn], dist[maxn][maxn];

 17 

 18 void ReadData()

 19 {

 20     int i, j;

 21     for ( i=1; i<=N; ++i )

 22     {

 23         for ( j=1; j<=N; ++j )

 24             scanf("%d", &edge[i][j]);

 25     }// graph

 26     for ( i=1; i<=N; ++i )

 27         scanf("%d", &tax[i]);

 28 }// ReadData

 29 

 30 void Initalize( int src, int dest )

 31 {

 32     for ( int i=1; i<=N; ++i )

 33     {

 34         for ( int j=1; j<=N; ++j )

 35         {

 36             path[i][j] = j;

 37             if ( j!=src && j!=dest && edge[i][j]!=0 && edge[i][j]!=-1 )

 38                 dist[i][j] = edge[i][j]+tax[j];

 39             else

 40                 dist[i][j] = ( edge[i][j]==-1 ) ? INF:edge[i][j];

 41         }

 42     }// End of for

 43     

 44     /*

 45     for ( int i=1; i<=N; ++i )

 46     {

 47         for ( int j=1; j<=N; ++j )

 48             printf("%10d ", dist[i][j]);

 49         printf("\n");

 50     }

 51     printf("\n");

 52     */

 53     

 54 }// Initalize

 55 

 56 void Floyd( int src )

 57 {

 58     for ( int k=1; k<=N; ++k )

 59     {

 60         for ( int i=1; i<=N; ++i )

 61         {

 62             for ( int j=1; j<=N; ++j )

 63             {

 64                 if ( k==i || k==j )    continue;

 65                 

 66                 int tt = dist[i][k]+dist[k][j];

 67                 if ( tt<dist[i][j] )

 68                     dist[i][j] = tt, path[i][j] = path[i][k];

 69                 else if ( tt==dist[i][j] && path[i][j]>path[i][k] )

 70                     path[i][j] = path[i][k];

 71             }

 72         }

 73     }// Loop

 74 }// Floyd

 75 /*

 76 void dfs( int ss, int tt )

 77 {

 78     if ( tt!=ss )

 79         dfs( ss, path[ss][tt] );

 80     

 81     if ( tt!=EndPoint )

 82         printf("%d-->", tt);

 83 }// dfs

 84 */

 85 void output( int src, int dest )

 86 {

 87     printf("From %d to %d :\nPath: %d", src, dest, src);

 88     

 89     int t = src;

 90     while ( t!=dest )

 91     {

 92         printf("-->%d", path[t][dest]);

 93         t = path[t][dest];

 94     }

 95 

 96     printf("\nTotal cost : %d\n\n", dist[src][dest]);

 97 }// output

 98 

 99 void Solve()

100 {

101     int ss, tt;

102     while ( ~scanf("%d %d", &ss, &tt), ss+tt!=-2 )

103     {

104         Initalize( ss, tt );

105         Floyd( ss );

106         output( ss, tt );

107     }// start point and destination

108 }// Solve

109 

110 int main()

111 {

112     while ( ~scanf("%d", &N), N!=0 )

113     {

114         ReadData();

115         Solve();

116     }// End of while

117     

118     return 0;

119 }

你可能感兴趣的:(floyd)