首页 > 代码库 > BZOJ 2165 大楼
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\n",ans+1); } int main() { scanf("%lld",&t); for (long long i=1;i<=t;i++) work(); return 0; }
BZOJ 2165 大楼
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。