博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zoj3497 Mistwald(矩阵快速幂)
阅读量:6176 次
发布时间:2019-06-21

本文共 2243 字,大约阅读时间需要 7 分钟。

题意:给定一个有向图(最多25个节点,每个节点的出度最多为4),给定起点和终点,然后从起点开始走,走到终点就停止,否则一直往下走,问能不能P步到达终点。也就是说从起点出发,走一条长度为P的路径,路径中间点不能经过终点(但可以反复经过其他点)。如果从起点出发P步后,不能到达终点,就是False,如果可以到达终点也可以到其他别的点,就是Maybe,如果P步后只能到达终点(到别的点没有长度为P的路径),则是Yes。

 

样例输入意思:四个坐标分别为,m*n矩阵中的坐标,通过次计算出每个节点对应的出口,然后建图。

 

分析:图的邻接矩阵A的 p次方Ap中为1的元素(i,j)表示节点i到节点j有一条长度为p的路径(经历的节点可能重复)。要理解矩阵的含义,两个矩阵相乘如果(x,y)元素为1,而(y,z)元素为1,则结果(x,z)元素为1,这表明通过y把x和z连起来了。而题目要求经过终点就不能走了,所以在做矩阵乘法时,需要把(x,n-1) (n-1,y)这样决定的(x,y)去掉。(n-1表示终点)。做乘法时,中间点小心一点就好了。矩阵乘法和floyd在本质上是一样的……

Orz..矩阵乘法还可以写成松弛操作。(是我辣鸡了)

 

 

矩阵的P次方运用的是经典的log(P)的算法。最后看一下结果矩阵的首行(0行)里面有几个1,以及(0,n-1)是不是1,来决定结果。

#include
#include
#include
#define maxn 30using namespace std;struct mat{ int a[maxn][maxn];};mat map;int mul;mat mat_mul(mat x,mat y){ mat ans; memset(ans.a,0,sizeof(ans.a)); for (int i=1;i<=mul;i++) for (int j=1;j<=mul;j++) for (int k=1;k<=mul;k++){ ans.a[i][j]+=x.a[i][k]*y.a[k][j]; } return ans;}mat mat_pow(mat map,int k){ //map的k次方 mat c=map,res=map; k--; while (k){ if (k&1) res=mat_mul(res,c); k>>=1; c=mat_mul(c,c); } return res;}int main(){ int t,m,n,q;char ch; int xx; int x[5],y[5]; scanf("%d",&t); while (t--){ scanf("%d%d",&m,&n);scanf("%c",&ch); mul=m*n; memset(map.a,0,sizeof(map.a)); for (int i=1;i<=m;i++){ for (int j=1;j<=n;j++){ scanf("((%d,%d),(%d,%d),(%d,%d),(%d,%d))",&x[0],&y[0],&x[1],&y[1],&x[2],&y[2],&x[3],&y[3]); scanf("%c",&ch); if (i==m && j==n) continue; //途中路径不能经过终点 for (int k=0;k<4;k++){ map.a[(i-1)*n+j][(x[k]-1)*n+y[k]]=1; } } } scanf("%d",&q); while (q--){ scanf("%d",&xx); mat S; if (xx) S=mat_pow(map,xx); else { memset(S.a,0,sizeof(S.a)); for (int i=0;i<=mul;i++) S.a[i][i]=1; } if (!S.a[1][mul]) printf("False\n"); else { int flag=0; for (int i=1;i

PS.迷之TLE无数发。各种迷。最后是因为快速幂姿势和别人有所不同,矩阵的0次方需要特判赋值为单位矩阵。orz....太菜了。

转载于:https://www.cnblogs.com/changer-qyz/p/8442857.html

你可能感兴趣的文章
第三天
查看>>
connector for python
查看>>
等价类划分的应用
查看>>
Web Service(下)
查看>>
trigger()
查看>>
nvm 怎么安装 ?
查看>>
Java VM里的magic
查看>>
[Node.js]Domain模块
查看>>
Linux操作系统文档
查看>>
利用Tensorflow训练自定义数据
查看>>
c++官方文档-枚举-联合体-结构体-typedef-using
查看>>
[题解]UVA11029 Leading and Trailing
查看>>
利用vue-gird-layout 制作可定制桌面 (一)
查看>>
校园社交网站app
查看>>
如何指定某些文件关闭ARC
查看>>
4、跃进表
查看>>
JAVA面向对象的总结(静态函数与static关键字)
查看>>
课堂作业第四周课上作业一
查看>>
使用Java语言开发微信公众平台(七)——音乐消息的回复
查看>>
陶哲轩实分析习题9.1.6
查看>>