AcWing 854 Floyd算法如何求解给定图的最短路径问题?

更新于
2026-10-10 09:47:07
3阅读来源:SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计704个文字,预计阅读时间需要3分钟。

AcWing 854 Floyd算法如何求解给定图的最短路径问题?

题目:给定一个包含点和边的有向图,图中可能存在重边和自环,边的权重为负数。再给定一个查询,每个查询包含两个整数 x 和 y,表示查询从点 x 到点 y 的最短距离。

输入:- 图的边数 n- 图的边列表,每条边包含起点、终点和权重- 查询数 k- 每个查询的起点 x 和终点 y

输出:- 对于每个查询,输出从点 x 到点 y 的最短距离

题目

给定一个 $n$ 个点 $m$ 条边的有向图,图中可能存在重边和自环,边权可能为负数。

再给定 $k$ 个询问,每个询问包含两个整数 $x$ 和 $y$,表示查询从点 $x$ 到点 $y$ 的最短距离,如果路径不存在,则输出 impossible。

数据保证图中不存在负权回路。

输入格式 第一行包含三个整数 $n,m,k$。

接下来 $m$ 行,每行包含三个整数 $x,y,z$,表示存在一条从点 $x$ 到点 $y$ 的有向边,边长为 $z$。

接下来 $k$ 行,每行包含两个整数 $x,y$,表示询问点 $x$ 到点 $y$ 的最短距离。

输出格式 共 $k$ 行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出 impossible。

AcWing 854 Floyd算法如何求解给定图的最短路径问题?

数据范围 $1≤n≤200,1≤k≤n^2,1≤m≤20000$,图中涉及边长绝对值均不超过 $10000$。

输入样例:

3 3 2 1 2 1 2 3 2 1 3 1 2 1 1 3

输出样例:

impossible 1

思路

Floyd基本思路

n -- 节点数 g -- 存放i到j的最短距离 for k in 1~n for i in 1~n for j in 1~n g[i][j] = min(g[i][j], g[i][k] + g[k][j])

代码

#include <iostream> using namespace std; const int N = 210, INF = 1e9; int n, m, z; int g[N][N]; void floyd() { // 对节点n进行3次循环 for (int k = 1; k <= n; k ++ ) for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) g[i][j] = min(g[i][j], g[i][k] + g[k][j]); } int main() { scanf("%d%d%d", &n, &m, &z); // 初始化 for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) { if (i == j) g[i][j] = 0; else g[i][j] = INF; } while (m -- ) { int a, b, c; scanf("%d%d%d", &a, &b, &c); g[a][b] = min(g[a][b], c); } floyd(); while (z -- ) { int x, y; scanf("%d%d", &x, &y); if (g[x][y] > INF / 2) puts("impossible"); else printf("%d\n", g[x][y]); } return 0; }

本文共计704个文字,预计阅读时间需要3分钟。

AcWing 854 Floyd算法如何求解给定图的最短路径问题?

题目:给定一个包含点和边的有向图,图中可能存在重边和自环,边的权重为负数。再给定一个查询,每个查询包含两个整数 x 和 y,表示查询从点 x 到点 y 的最短距离。

输入:- 图的边数 n- 图的边列表,每条边包含起点、终点和权重- 查询数 k- 每个查询的起点 x 和终点 y

输出:- 对于每个查询,输出从点 x 到点 y 的最短距离

题目

给定一个 $n$ 个点 $m$ 条边的有向图,图中可能存在重边和自环,边权可能为负数。

再给定 $k$ 个询问,每个询问包含两个整数 $x$ 和 $y$,表示查询从点 $x$ 到点 $y$ 的最短距离,如果路径不存在,则输出 impossible。

数据保证图中不存在负权回路。

输入格式 第一行包含三个整数 $n,m,k$。

接下来 $m$ 行,每行包含三个整数 $x,y,z$,表示存在一条从点 $x$ 到点 $y$ 的有向边,边长为 $z$。

接下来 $k$ 行,每行包含两个整数 $x,y$,表示询问点 $x$ 到点 $y$ 的最短距离。

输出格式 共 $k$ 行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出 impossible。

AcWing 854 Floyd算法如何求解给定图的最短路径问题?

数据范围 $1≤n≤200,1≤k≤n^2,1≤m≤20000$,图中涉及边长绝对值均不超过 $10000$。

输入样例:

3 3 2 1 2 1 2 3 2 1 3 1 2 1 1 3

输出样例:

impossible 1

思路

Floyd基本思路

n -- 节点数 g -- 存放i到j的最短距离 for k in 1~n for i in 1~n for j in 1~n g[i][j] = min(g[i][j], g[i][k] + g[k][j])

代码

#include <iostream> using namespace std; const int N = 210, INF = 1e9; int n, m, z; int g[N][N]; void floyd() { // 对节点n进行3次循环 for (int k = 1; k <= n; k ++ ) for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) g[i][j] = min(g[i][j], g[i][k] + g[k][j]); } int main() { scanf("%d%d%d", &n, &m, &z); // 初始化 for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) { if (i == j) g[i][j] = 0; else g[i][j] = INF; } while (m -- ) { int a, b, c; scanf("%d%d%d", &a, &b, &c); g[a][b] = min(g[a][b], c); } floyd(); while (z -- ) { int x, y; scanf("%d%d", &x, &y); if (g[x][y] > INF / 2) puts("impossible"); else printf("%d\n", g[x][y]); } return 0; }