Floyd算法求最短路径,长尾词如何应用?

2026-04-12 05:182阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

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

Floyd算法求最短路径,长尾词如何应用?

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

再给定一个询问 $k$,每个询问包含两个整数 $x$ 和 $y$,表示查询从点 $x$ 到点 $y$ 的最短距离。

Floyd算法求最短路径,长尾词如何应用?

题目

给定一个 $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

数据范围 $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; }

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

Floyd算法求最短路径,长尾词如何应用?

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

再给定一个询问 $k$,每个询问包含两个整数 $x$ 和 $y$,表示查询从点 $x$ 到点 $y$ 的最短距离。

Floyd算法求最短路径,长尾词如何应用?

题目

给定一个 $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

数据范围 $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; }