……

解题报告:luogu P1613

题目链接:P1613 跑路
二进制的神奇应用。
考虑 \(dis_{i,j}\)在为 \(2^s\) 时存在,意味着存在断点 \(k\) 满足 \(dis_{i,k}\)\(dis_{k,j}\)\(2^{s-1}\)时存在,我们根据这个东西进行递推。
然后处理出所有可行路线,进行 \(floyd\) 即可(当然 \(dij\)\(SPFA\) 啥的都行。
又没做出来,\(qwq\)......

\(Code\):

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

#define read(x) scanf("%d",&x)
#define ll long long
#define inf 1ll<<60

int n,m,l,r;
ll dis[55][55];
int minx[55][55][64];

int main()
{
	read(n),read(m);
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=inf;
	for(int i=1;i<=m;i++) read(l),read(r),dis[l][r]=1,minx[l][r][0]=1;
	for(int s=1;s<=64;s++)
	{
		for(int k=1;k<=n;k++)
		{
			for(int i=1;i<=n;i++)
			{
				for(int j=1;j<=n;j++) if(minx[i][k][s-1]&&minx[k][j][s-1]) minx[i][j][s]=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\n",dis[1][n]);
	return 0;
}
posted @ 2020-04-18 21:22  童话镇里的星河  阅读(104)  评论(0编辑  收藏  举报