题目提示很明显,要倍增。
于是倍增处理 $u,v$ 是否能一步到达,然后 Floyd。
费斯德勒找的到底是什么抽象题目啊,难度跨度这么大。
#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 65;
int n, m;
bool f[N][N][M];
int d[N][N];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i <= m; i++) {
scanf("%d%d", &u, &v);
f[u][v][0] = 1;
}
for (int i = 1; i <= 64; i++)
for (int u = 1; u <= n; u++)
for (int v = 1; v <= n; v++)
for (int w = 1; w <= n; w++) {
f[u][v][i] |= f[u][w][i - 1] & f[w][v][i - 1];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
if (i == j) d[i][j] = 0;
else d[i][j] = 0x3f3f3f3f;
}
for (int i = 0; i <= 64; i++)
for (int u = 1; u <= n; u++)
for (int v = 1; v <= n; v++)
if (f[u][v][i]) d[u][v] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
printf("%d\n", d[1][n]);
return 0;
}