Luogu P1613 跑路 题解 [ 蓝 ] [ 倍增 ] [ Floyd 最短路 ] [ 状压 dp ]
跑路:绝佳倍增好题,思路是化
最近不知道是撞了什么运,前一脚看的是绿题,写完之后交一发,发现直接被 lxl 升蓝了,血赚。
思路:Floyd
首先观察到每次走
但为了让这题的代码更好实现一些,观察到
于是转移方程就出来了,我们枚举一下中点
这样我们就求出某个点能否用
接下来就直接建边,跑 Floyd 或者其他乱七八糟的算法求最短路即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
int n,m,f[55][55];
bitset<55>g[70][55];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
//prepare
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
g[0][u][v]=1;
}
for(int i=1;i<=64;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
for(int l=1;l<=n;l++)
{
g[i][j][k]=g[i][j][k]|(g[i-1][j][l]&g[i-1][l][k]);
}
}
}
}
//build graph
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)f[i][i]=0;
for(int i=0;i<=64;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
if(g[i][j][k]==1)f[j][k]=min(f[j][k],1);
}
}
}
//Floyd
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
}
cout<<f[1][n];
return 0;
}
思路:状压 dp
口胡一下,和上面的那种方法差不多。
首先用 vector 记录下从点
接下来从
注意状态用 ll 存,int 开不下。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战