正题
题目链接:https://www.luogu.org/problem/P1613
题目大意
询问111到nnn的路径,每次可以走2n2^n2n条边,求最少次数(可以重复)。
解题思路
定义geti,j,tget_{i,j,t}geti,j,t表示iii到jjj是否有2t2^t2t的路径。
然后geti,j,t=geti,k,t−1&getk,j,t−1get_{i,j,t}=get_{i,k,t-1}\&get_{k,j,t-1}geti,j,t=geti,k,t−1&getk,j,t−1
最后跑一遍FloydFloydFloyd即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=51;
int n,m,dis[N][N],get[N][N][65];
int main()
{scanf("%d%d",&n,&m);memset(dis,0x3f,sizeof(dis));for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);dis[x][y]=1;get[x][y][0]=1;}for(int t=1;t<=64;t++)for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(get[i][k][t-1]&&get[k][j][t-1])get[i][j][t]=1,dis[i][j]=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]);printf("%d",dis[1][n]);
}