main
黄海 2 years ago
parent 2e000d82a6
commit d68d2881ba

@ -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];

Loading…
Cancel
Save