BZOJ 2165: 大楼 倍增Floyd

时间:2019-09-20
本文章向大家介绍BZOJ 2165: 大楼 倍增Floyd,主要包括BZOJ 2165: 大楼 倍增Floyd使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Code: 

#include <bits/stdc++.h>  
#define N 202 
#define M 55     
#define ll long long  
#define inf -1    
#define setIO(s) freopen(s".in","r",stdin)  // , freopen("de.out","w",stdout)     
using namespace std;       
int n;      
ll m;  
ll f[N][N],dis[N][N][70],tmp[N][N],g[N][N];        
void solve() 
{ 
    int i,j,k;      
    scanf("%d%lld",&n,&m);  
    memset(dis,-1,sizeof(dis));  
    for(i=1;i<=n;++i) 
    { 
        for(k=0;k<=M;++k) 
            dis[i][i][k]=0;     
    } 
    for(i=1;i<=n;++i) 
    {
        for(j=1;j<=n;++j) 
        {
            ll p; 
            scanf("%lld",&p);   
            if(p) 
            {
                dis[i][j][0]=max(dis[i][j][0], p); 
            }
        }
    }       
    for(int l=1;;++l)                                  
    { 
        for(k=1;k<=n;++k) 
        { 
            for(i=1;i<=n;++i) 
            {
                for(j=1;j<=n;++j) 
                { 
                    if(dis[i][k][l-1]!=-1 && dis[k][j][l-1]!=-1)  
                    {   
                        dis[i][j][l]=max(dis[i][j][l], dis[i][k][l-1]+dis[k][j][l-1]);         
                    }
                }
            }
        } 
        ll re=0;    
        for(i=1;i<=n;++i) re=max(re, dis[1][i][l]); 
        if(re>=m) {
            i=l;   
            break;     
        }
    }                
    int flag=0; 
    ll ans=0;   
    memset(tmp,-1,sizeof(tmp));          
    for(int l=i;l>=0;--l) 
    {   
        if(!flag) 
        {     
            flag=1;      
            for(i=1;i<=n;++i) 
            {
                if(dis[1][i][l]>=m) 
                {
                    flag=0; 
                }
            } 
            if(flag==0) continue; 
            else 
            { 
                for(i=1;i<=n;++i) 
                    for(j=1;j<=n;++j) tmp[i][j]=dis[i][j][l]; 
                ans+=(1ll<<l);    
            }            
        }
        else 
        {
            memset(g,-1,sizeof(g));    
            for(k=1;k<=n;++k) 
            {
                for(i=1;i<=n;++i)          
                {
                    for(j=1;j<=n;++j) 
                    {
                        if(dis[i][k][l]!=inf && tmp[k][j]!=inf) 
                        {
                            g[i][j]=max(g[i][j], dis[i][k][l]+tmp[k][j]);   
                        }
                    }
                }
            }       
            int cc=0; 
            for(i=1;i<=n;++i) if(g[1][i]>=m) cc=1;   
            if(!cc) 
            {    
                for(i=1;i<=n;++i) 
                    for(j=1;j<=n;++j) tmp[i][j]=g[i][j];  
                ans+=(1ll<<l);    
            } 
        }
    }
    printf("%lld\n",ans+1);    
}
int main() 
{ 
    // setIO("input");
    int T; 
    scanf("%d",&T); 
    while(T--) 
    {
        solve(); 
    }
    return 0;   
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11555924.html