BZOJ 2165 大楼

Posted on 2016-10-19 19:00  ziliuziliu  阅读(165)  评论(0编辑  收藏  举报

倍增floyd然后按位确定。

注意long long的时候要1LL<i!!!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 105
#define inf 1e18
using namespace std;
long long t,n,m,f[maxn][maxn][maxn],g[maxn][maxn],h[maxn][maxn];
bool check(long long x)
{
    for (long long i=1;i<=n;i++)
        if (f[x][1][i]>=m)
            return true;
    return false;
}
bool judge(long long x)
{
    for (long long i=1;i<=n;i++)
        for (long long j=1;j<=n;j++)
            h[i][j]=-inf;
    for (long long i=1;i<=n;i++)
        for (long long j=1;j<=n;j++)
        {
            for (long long k=1;k<=n;k++)
                h[i][j]=max(g[i][k]+f[x][k][j],h[i][j]);
            if (h[i][j]>m) h[i][j]=m;
        }
    for (long long i=1;i<=n;i++)
        if (h[1][i]>=m) return false;
    return true;
}
void work()
{
    scanf("%lld%lld",&n,&m);
    memset(f,0,sizeof(f));memset(g,0,sizeof(g));
    for (long long i=1;i<=n;i++)
        for (long long j=1;j<=n;j++)
        {
            scanf("%lld",&f[0][i][j]);
            if (!f[0][i][j]) f[0][i][j]=-inf;
        }
    long long p=0;
    if (!check(p))
    {
        for (p=1;;p++)
        {
            for (long long i=1;i<=n;i++)
                for (long long j=1;j<=n;j++)
                    f[p][i][j]=-inf;
            for (long long i=1;i<=n;i++)    
                for (long long j=1;j<=n;j++)
                {
                    for (long long k=1;k<=n;k++)
                        f[p][i][j]=max(f[p][i][j],f[p-1][i][k]+f[p-1][k][j]);
                    if (f[p][i][j]>m) f[p][i][j]=m;
                }
            if (check(p)) break;
        }
        p--;
    }
    long long ans=(1LL<<p);
    for (long long i=1;i<=n;i++)
        for (long long j=1;j<=n;j++)
            g[i][j]=f[p][i][j];
    for (long long i=p-1;i>=0;i--)
    {
        if (judge(i))
        {
            ans+=(1LL<<i);
            memcpy(g,h,sizeof(g));
        }
    }
    printf("%lld\n",ans+1);
}
int main()
{
    scanf("%lld",&t);
    for (long long i=1;i<=t;i++)
        work();
    return 0;
}