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)
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }