• 【题解】P1613跑路


    【题解】P1613 鸽王跑路

    一道思维好题!

    考虑(2^k)的传递性。直接64遍(floyd)求所有(2^k)的路径,转移方程是

    (dp(i,j,k)=[dp[i][t][k-1])&&(dp[t][j]][k-1])

    有了这个之后先(O(n^3))预处理,然后根据这样的数组直接建边跑最短路即可。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<bitset>
    #include<vector>
    #include<map>
    #include<ctime>
    #include<cstdlib>
    #include<set>
    #include<bitset>
    #include<stack>
    #include<list>
    #include<cmath>
    using namespace std;
    #define RP(t,a,b) for(register int (t)=(a),edd_=(b);t<=edd_;++t)
    #define DRP(t,a,b) for(register int (t)=(a),edd_=(b);t>=edd_;--t)
    #define ERP(t,a) for(int t=head[(a)];t;t=e[t].nx)
    #define Max(a,b) ((a)<(b)?(b):(a))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define TMP template<class ccf>
    typedef long long ll;
    TMP inline ccf qr(ccf k){
        char c=getchar();
        ccf x=0;
        int q=1;
        while(c<48||c>57)
        q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)
        x=x*10+c-48,c=getchar();
        if(q==-1)
        x=-x;
        return x;
    }
    
    int m,n;
    const int maxn=55;
    bool d[maxn][maxn][71];
    inline void add(int fr,int to){
        d[fr][to][0]=1;
    }
    
    const int maxe=51*51*15;
    struct E{
        int to,nx;
    }e[maxe];
    int head[maxn];
    int cnt;
    inline void add2(int fr,int to){
        e[++cnt]=(E){to,head[fr]};
        head[fr]=cnt;
    }
    
    int t1,t2;
    queue< int > q;
    int ans[maxn];
    bool in[maxn];
    const int inf=0x3f3f3f3f;
    inline void spfa(){
        RP(t,1,n)
        ans[t]=inf;
        ans[1]=0;
        in[1]=1;
        q.push(1);
        while(!q.empty()){
        t1=q.front();
        q.pop();
        in[t1]=0;
        ERP(t,t1){
            if(ans[e[t].to]>ans[t1]+1){
            ans[e[t].to]=ans[t1]+1;
            if(!in[e[t].to])
                q.push(e[t].to);
            in[e[t].to]=1;
            }
        }
        }
    }
    
    
    
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        n=qr(1);
        m=qr(1);
        RP(t,1,m){
        t1=qr(1);
        t2=qr(1);
        add(t1,t2);
        }
       
        RP(k,0,65){
        RP(i,1,n){
            RP(t,1,n){
            RP(f,1,n){
                d[t][f][k+1]|=(d[t][i][k]&&d[i][f][k]);
            }
            }
        }
        }
        
        RP(t,1,n){
        RP(i,1,n){
            if(t==i)
            continue;
            RP(k,0,65){
            if(d[t][i][k]){
                add2(t,i);
                break;
            }
            }
        }
        }
    
        spfa();
        cout<<ans[n]<<endl;
        return 0;
    }
    
    
    
    
    
    
  • 相关阅读:
    ADO.NET存取数据库数据
    2017-01-03
    re模块
    random模块(随机)
    sys模块
    os模块
    datetime模块
    time模块
    logging模块
    Python函数初识
  • 原文地址:https://www.cnblogs.com/winlere/p/10333914.html
Copyright © 2020-2023  润新知