zoukankan      html  css  js  c++  java
  • BZOJ 2165 大楼

    倍增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
    ",ans+1);
    }
    int main()
    {
        scanf("%lld",&t);
        for (long long i=1;i<=t;i++)
            work();
        return 0;
    }
  • 相关阅读:
    数位DP入门
    划分树
    CodeForces #362 div2 B. Barnicle
    CodeForces #363 div2 Vacations DP
    CodeForces #368 div2 D Persistent Bookcase DFS
    解决Ubuntu 下 vi编辑器不能使用方向键和退格键问题
    python之爬虫爬有道词典
    hdu 5145 NPY and girls 莫队
    hdu 6185 Covering 矩阵快速幂
    字典树求异或值
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5978393.html
Copyright © 2011-2022 走看看