P1613 跑路 题解
思维题。
我们考虑用倍增。
表示从 到 有一条长度为 的路径。
转移方程为:
假设有三个点 。
如果 且 , 则 。
倍增的常见思路。
如果两个点直接能有一条 的路径,就在两点直接建一条边。
然后跑个最短路就行了。
/* Work by: TLE_Automation */ #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define LL long long #define int long long using namespace std; const int N = 1e6 + 10; const int MAXN = 2e5 + 10; inline char readchar() { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; } inline int read() { #define readchar getchar int res = 0, f = 0;char ch = readchar(); for(; !isdigit(ch); ch = readchar()) if(ch == '-') f = 1; for(; isdigit(ch); ch = readchar()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res; } inline void print(int x) { if (x < 0 ) putchar('-'), x = -x; if (x > 9 ) print(x / 10); putchar(x % 10 + '0'); } int cnt = 0, head[MAXN]; int f[52][52][70], dis[100][100]; int n, m; signed main() { n = read(), m = read(); memset(dis, 0x3f, sizeof dis); for(int i = 1, u, v; i <= m; i++) { u = read(), v = read(); dis[u][v] = 1, f[u][v][0] = 1; } for(int M = 1; M <= 64; M++) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { for(int k = 1; k <= n; k++) { if(f[i][j][M - 1] != 0 && f[j][k][M - 1] != 0) f[i][k][M] = 1, dis[i][k] = 1; } } } } for(int k = 1; k <= n; k++) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } } } cout << dis[1][n]; }
本文作者:TLE_Automation
本文链接:https://www.cnblogs.com/tttttttle/p/16311183.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!