BZOJ 2165: 大楼 倍增Floyd

卡了一上午常数,本地13s,可是bzoj 就是过不去~

#include <bits/stdc++.h>  
#define N 102 
#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;      
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rdint() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
ll rdll() {ll x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;} 
int n;      
ll m;  
ll f[N][N],dis[N][N][70],tmp[N],g[N];        
void solve() 
{ 
    int i,j,k;      
    n=rdint(); 
    m=rdll();    
    for(i=0;i<=n;++i) 
        for(j=0;j<=n;++j) 
            for(k=0;k<70;++k) dis[i][j][k]=-1;      
    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=rdll();   
            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;             
    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[j]=dis[1][j][l]; 
                ans+=(1ll<<l);    
            }            
        }
        else 
        {
            for(i=0;i<=n;++i) g[i]=-1;      
            for(k=1;k<=n;++k) 
            {     
                for(j=1;j<=n;++j) 
                {
                    if(dis[k][j][l]!=inf && tmp[k]!=inf) 
                    {
                        g[j]=max(g[j], tmp[k]+dis[k][j][l]);   
                    }
                } 
            }       
            int cc=0; 
            for(i=1;i<=n;++i) if(g[i]>=m) cc=1;   
            if(!cc) 
            {    
                for(j=1;j<=n;++j) tmp[j]=g[j];  
                ans+=(1ll<<l);    
            } 
        }
    }
    printf("%lld
",ans+1);    
}
int main() 
{ 
    // setIO("input");
    int T; 
    scanf("%d",&T); 
    while(T--) 
    {
        solve(); 
    }
    return 0;   
}

  

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