Luogu1613 跑路-倍增+Floyd

Solution

挺有趣的一道题, 仔细想想才想出来

先用$mp[i][j][dis]$ 是否存在一条 $i$ 到 $j$ 的长度为 $2^{dis}$ 的路径。

转移 :

 for (int dis = ; dis < base; ++dis)
for (int k = ; k <= n; ++k)
for (int i = ; i <= n; ++i) if (mp[i][k][dis - ])
for (int j = ; j <= n; ++j) if (mp[k][j][dis - ])
mp[i][j][dis] = ;

若$mp[i][j][dis] = 1$, 则把 $f[i][j]$ 记为$1$

然后再用$f[i][j]$ 去跑$Floyd$。 这样找出的路径 一定是最短的(因为能合成 $2^dis$ 的路径都已经被记录了

Code

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rd read()
using namespace std; const int N = ;
const int base = ; int mp[N][N][N], f[N][N];
int n, m; int read() {
int X = , p = ; char c = getchar();
for (; c > '' || c < ''; c = getchar())
if (c == '-') p = -;
for (; c >= '' && c <= ''; c = getchar())
X = X * + c - '';
return X * p;
} void cmin(int &A, int B) {
if (A > B) A = B;
} int main()
{
n = rd; m = rd;
memset(f, , sizeof(f));
for (int i = ; i <= m; ++i) {
int u = rd, v = rd;
mp[u][v][] = ;
}
for (int dis = ; dis < base; ++dis)
for (int k = ; k <= n; ++k)
for (int i = ; i <= n; ++i) if (mp[i][k][dis - ])
for (int j = ; j <= n; ++j) if (mp[k][j][dis - ])
mp[i][j][dis] = ;
for (int dis = ; dis < base; ++dis)
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j) if (mp[i][j][dis])
f[i][j] = ;
for (int k = ; k <= n; ++k)
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
cmin(f[i][j], f[i][k] + f[k][j]);
printf("%d\n", f[][n]);
}
上一篇:python调用另一个.py文件中的类和函数


下一篇:耳机jack构造及在应用时可能出现的问题