From 7239d0a40a920ff3a4df8c1b8dc12adf8c06eb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Fri, 5 Jan 2024 15:10:48 +0800 Subject: [PATCH] 'commit' --- TangDou/Topic/SSL1613.cpp | 43 +++++++++++++++ TangDou/Topic/【Floyd专题】.md | 84 +++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 TangDou/Topic/SSL1613.cpp diff --git a/TangDou/Topic/SSL1613.cpp b/TangDou/Topic/SSL1613.cpp new file mode 100644 index 0000000..5d667dc --- /dev/null +++ b/TangDou/Topic/SSL1613.cpp @@ -0,0 +1,43 @@ +#include +using namespace std; +int o(int t) { + return t * t; +} +const int N = 110; +int n, m, x[N], y[N]; +double g[N][N]; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> x[i] >> y[i]; + + // double类型的数组,初始化不能用memset!!!! + // memset(g, 0x3f, sizeof g); + // for (int i = 0; i <= n; i++) g[i][i] = 0; + + // 需要用二重循环进行初始化 + 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] = 0x3f3f3f3f; + } + + cin >> m; + int l, r; + while (m--) { + cin >> l >> r; + g[r][l] = g[l][r] = sqrt((double)o(x[l] - x[r]) + (double)o(y[l] - y[r])); // 勾股定理 + } + + // floyd + for (int k = 1; k <= n; k++) + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) + if (g[i][j] > g[i][k] + g[k][j]) g[i][j] = g[i][k] + g[k][j]; + + cin >> l >> r; + printf("%.2lf", g[l][r]); + return 0; +} diff --git a/TangDou/Topic/【Floyd专题】.md b/TangDou/Topic/【Floyd专题】.md index bf389d1..2843186 100644 --- a/TangDou/Topic/【Floyd专题】.md +++ b/TangDou/Topic/【Floyd专题】.md @@ -532,7 +532,87 @@ int main() { } ``` -SSL-1613=CCF1342(最短路径问题) -SSL-1761(城市问题) +#### [$SSL-1613$]() +> Description +平面上有$n$个点($N<=100$),每个点的坐标均在$-10000\sim 10000$之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点直线的 **距离** 。现在的任务是找出从一点到另一点之间的最短路径。 +$Input$ +输入文件$short.in$,共有$n+m+3$行,其中: +第一行为一个整数$n$。 +第$2$行到第$n+1$行(共$n$行),每行的两个整数$x$和$y$,描述一个点的坐标(以一个空格隔开)。 + +第$n+2$行为一个整数$m$,表示图中的连线个数。 +此后的$m$行,每行描述一条连线,由两个整数$i,j$组成,表示第$i$个点和第$j$个点之间有连线。 +最后一行:两个整数$s$和$t$,分别表示源点和目标点。 + +$Output$ +输出文件$short.out$仅一行,一个实数(保留两位小数),表示从$S$到$T$的最短路径的长度。 + +$Sample$ $Input$ +```cpp {.line-numbers} +5 +0 0 +2 0 +2 2 +0 2 +3 1 +5 +1 2 +1 3 +1 4 +2 5 +3 5 +1 5 +``` + +Sample Output +```cpp {.line-numbers} +3.41 +``` + +#### $Code$ +```cpp {.line-numbers} +#include +using namespace std; +int o(int t) { + return t * t; +} +const int N = 110; +int n, m, x[N], y[N]; +double g[N][N]; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> x[i] >> y[i]; + + // double类型的数组,初始化不能用memset!!!! + // memset(g, 0x3f, sizeof g); + // for (int i = 0; i <= n; i++) g[i][i] = 0; + + // 需要用二重循环进行初始化 + 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] = 0x3f3f3f3f; + } + + cin >> m; + int l, r; + while (m--) { + cin >> l >> r; + g[r][l] = g[l][r] = sqrt((double)o(x[l] - x[r]) + (double)o(y[l] - y[r])); // 勾股定理 + } + // floyd + for (int k = 1; k <= n; k++) + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) + if (g[i][j] > g[i][k] + g[k][j]) g[i][j] = g[i][k] + g[k][j]; + + cin >> l >> r; + printf("%.2lf", g[l][r]); + return 0; +} +``` \ No newline at end of file