序言:
老师说会考一道最短路的题我好像听到了
然后看到了最后一题是最短路,然后就没有往这方面想。
所以我来写一下,最短路的t题解和思路。
题目描述:
有 n 个人,他们的编号为 1~n,其中有一些人相互认识,现在 x 想要认识 y,可以通过他所认识的人来认识更多的人(如果 a 认识 b,b 认识 c,那么 a 可以通过 b 来认识 c),求出 x 最少需要通过多少人才能认识 y。
输入格式:
输入格式 第 1 行 3 个整数 n、x、y,2≤n≤100; 接下来的 n 行是一个 n×n 的邻接矩阵, a[i][j]=1 表示 i 认识 j,a[i][j]=0 表示不认识。 保证 i=j 时,a[i][j]=0,并且 a[i][j]=a[j][i]。
输出格式:
输出格式 一行一个整数,表示 x 认识 y 最少需要通过的人数。数据保证 x 一定能认识 y。
样例输入:
5 1 5
0 1 0 0 0
1 0 1 1 0
0 1 0 1 0
0 1 1 0 1
0 0 0 1 0
样例输出:
2
题目分析与思路:
他需要通过多少人才能认识某个其他人。
其实就是他最少需要经过多少个点才能到达终点。
就是一道显而易见的 F l o y d Floyd Floyd,但是我没看出来。。。
代码:
#include <cstdio>
#include <cstring>
const int MAXN = 105;
int n, x, y, a[MAXN][MAXN];
int Min(int one, int two) {
return one < two ? one : two;
}
int main() {
memset(a, 0x3f, sizeof(a));
scanf("%d%d%d", &n, &x, &y);
for (int i = 1; i <= n; i++) {
a[i][i] = 0;
for (int j = 1; j <= n; j++) {
int tmp;
scanf("%d", &tmp);
if (tmp != 0) {
a[i][j] = Min(a[i][j], tmp);
}
}
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i != j && i != k && j != k) {
a[i][j] = Min(a[i][j], a[i][k] + a[k][j]);
}
}
}
}
if (a[x][y] != 0) {
printf("%d", a[x][y] - 1);
}
else {
printf("0");
}
return 0;
}
总结:
看来一道板子题,不考你难度,但是取决于你能不能看出来他是一个板子题。我现在是过于依赖看题目标签,知道了这道题的类型才会做这个习惯应该改变,应该从题目描述开始找这道题的类型。