【Luogu】P1613跑路(倍增+Floyd)

题目链接在此

   其实我看到这道题一点想法都没有

   设f[i][j][k]表示用2i秒能不能从j走到k。如果可以,那j到k就可以一秒走到,它们的路径长度就是1。方程为f[i][j][k]=f[i-1][j][l]&&f[i-1][l][k]。

   最后在图上跑一遍Floyd。复杂度O(n3)。

   代码如下

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<cstring>
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

bool f[65][55][55];
int Map[55][55];
int q[1000000],h,t;
int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)    Map[i][j]=65;
    for(int i=1;i<=m;++i){
        int from=read(),to=read();
        f[0][from][to]=1;
        Map[from][to]=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)
                    if(f[i-1][j][k]&&f[i-1][k][l])
                        f[i][j][l]=Map[j][l]=1;
    for(int j=1;j<=n;++j)
        for(int i=1;i<=n;++i)
            for(int k=1;k<=n;++k)
                if(Map[i][j]+Map[j][k]<Map[i][k])    Map[i][k]=Map[i][j]+Map[j][k];
    printf("%d",Map[1][n]);
    return 0;
}
原文地址:https://www.cnblogs.com/cellular-automaton/p/7467383.html