「luogu1613」跑路

传送门
Luogu

解题思路

对于所有可以用 (2^k) 形式表示的 (dis(i,j)),将(i,j)之间的 (dis) 置为 (1),可以用倍增 ( ext{Floyd}) 实现。
然后直接 ( ext{Floyd}) 最短路即可。

细节注意事项

  • 记得开( ext{long long})

参考代码

#include <cstdio>
#define rg register
#define int long long 
const int MAXN = 55;
inline int min(int a, int b) { return a < b ? a : b; }
inline int read() {
	int s = 0; bool f = false; char c = getchar();
	while (c < '0' || c > '9') f |= (c =='-'), c = getchar();
	while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
	return f ? -s : s;
}
bool g[MAXN][MAXN][70];
int dis[MAXN][MAXN];
signed main() {
	int n = read(), m = read();
	for (rg int i = 1; i <= n; ++i)
		for (rg int j = 1; j <= n; ++j)
			dis[i][j] = 0x7f7f7f7f;
	for (rg int i = 1; i <= m; ++i) {
		int u = read(), v = read();
		dis[u][v] = 1, g[u][v][0] = true;
	}
	for (rg int t = 1; t <= 64; ++t)
		for (rg int k = 1; k <= n; ++k)
			for (rg int i = 1; i <= n; ++i)
				for (rg int j = 1; j <= n; ++j)
					if (g[i][k][t - 1] && g[k][j][t - 1])
						g[i][j][t] = true, dis[i][j] = 1;
	for (rg int k = 1; k <= n; ++k)
		for (rg int i = 1; i <= n; ++i)
			for (rg int j = 1; j <= n; ++j)
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	printf("%lld
", dis[1][n]);
	return 0;
}

完结撒花 (qwq)

原文地址:https://www.cnblogs.com/zsbzsb/p/11745754.html