diff --git a/TangDou/Topic/HDU1385.cpp b/TangDou/Topic/HDU1385.cpp index be7581b..93e6bac 100644 --- a/TangDou/Topic/HDU1385.cpp +++ b/TangDou/Topic/HDU1385.cpp @@ -3,20 +3,22 @@ using namespace std; const int INF = 0x3f3f3f3f; const int N = 1003; -int g[N][N], path[N][N]; // 邻接矩阵、路径 -int n, x, y, w[N]; // 额外费用 +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) + 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]) { - g[i][j] = g[i][k] + g[k][j] + w[k]; + 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]) { - if (path[i][j] > path[i][k]) // 字典序 - 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]; // 字典序,谁更小就留下谁 } } } @@ -31,13 +33,16 @@ int main() { } 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 = path[x][y];