2165: 大楼 倍增floyd
2016-01-08 08:26
211 查看
虽然A掉了……但还是有点不明白的地方QAQ,我还是太弱了。
首先倍增floyd或矩阵乘法无误(实质上是差不多的),用f[p][i][j]表示走了2^p步从第i个房间到第j个房间最多上升了几层,转移显然:f[p][i][j]=max(f[p-1][i][k]+f[p-1][k][j])。
当存在f[p][i][j]>=m时,即出现了合法的解,但此时的意义是:走了2^p步到了m层或以上的地方,但这2^p步中可能存在从m层以上继续往上走的情况,而根据题目这些步其实是冗余的,我们应将其去掉。于是我们可以用g[i][j]表示目前从i到j最长路是多长,注意这个定义和f是有区别的,g[i][j]并没有步数的限制,那么我们在枚举p的时候,如果当前的MAX(f[p][i][k]+g[k][j])>=m,我们就break,否则就加上1 << p,这样最后得到的答案是一个接近于m但小于m的值,我们再走一步即可到达m及以上,所以输出ans+1。
首先倍增floyd或矩阵乘法无误(实质上是差不多的),用f[p][i][j]表示走了2^p步从第i个房间到第j个房间最多上升了几层,转移显然:f[p][i][j]=max(f[p-1][i][k]+f[p-1][k][j])。
当存在f[p][i][j]>=m时,即出现了合法的解,但此时的意义是:走了2^p步到了m层或以上的地方,但这2^p步中可能存在从m层以上继续往上走的情况,而根据题目这些步其实是冗余的,我们应将其去掉。于是我们可以用g[i][j]表示目前从i到j最长路是多长,注意这个定义和f是有区别的,g[i][j]并没有步数的限制,那么我们在枚举p的时候,如果当前的MAX(f[p][i][k]+g[k][j])>=m,我们就break,否则就加上1 << p,这样最后得到的答案是一个接近于m但小于m的值,我们再走一步即可到达m及以上,所以输出ans+1。
[code]#include<bits/stdc++.h> #define ll long long using namespace std; int T,n,p; bool flag; ll f[70][105][105],g[105][105],t[105][105],ans,m; inline ll read() { ll a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f; } inline void work1() { for (p=1;(1ll<<p)<=m;p++) for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { f[p][i][j]=max(f[p-1][i][k]+f[p-1][k][j],f[p][i][j]); if (i==1&&f[p][i][j]>=m) return; } } inline void work2() { memset(t,0xef,sizeof(t)); for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { t[i][j]=max(t[i][j],f[p][i][k]+g[k][j]); if (i==1&&t[i][j]>=m) return; } memcpy(g,t,sizeof(g)); ans+=1ll<<p; } int main() { T=read(); while (T--) { n=read(); m=read(); memset(f,0xef,sizeof(f)); memset(g,0xef,sizeof(g)); for (int i=1;i<=n;i++) g[i][i]=0; ans=0; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { f[0][i][j]=read(); if (!f[0][i][j]) f[0][i][j]=-1e18; } work1(); while (p--) work2(); printf("%lld\n",ans+1); } return 0; }
相关文章推荐
- 130_Bribe the Prisoners 囚徒贿赂问题 (2009 Round1C C)
- 花开的季节,携梦想归来(一)
- 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月8日)
- Product of Array Except Self
- [leetcode] 143. Reorder List 解题报告
- linux 隐藏及显示文件或目录
- 括号配对问题(南阳2)
- 聆听机器人小冰发声有感
- 4. Autolayout技术和Autoresizing技术
- 升级Win10遭遇错误代码0xc0000017的解决办法
- Machine Learning 101
- uva10341 - solve it (二分查找)
- PHP操作数据库
- Maven项目中mvn clean后找不到測试类问题
- VS2010调用VLFeat
- navicat for mysql 10.1.7注册码
- java中Math的一些用法
- HTML中<input>參数,以及文本输入框,文本域的解说
- 数据库操作增删改查
- Java时间比較