首页 > 代码库 > BZOJ 1297 SCOI2009 迷路 矩阵乘法
BZOJ 1297 SCOI2009 迷路 矩阵乘法
题目大意:给定一个邻接矩阵,求1~n的边权恰好为T的路径条数
考虑当所有边权都是1的时候 那么显然邻接矩阵自乘T次之后a[1][n]就是答案
因为当边权为1的时候a[i][j]可以表示从第i个点转移到第j个点的方案数 显然这个符合矩乘的定义
现在边权最大为9 那么将一个点拆成9个 第i个点拆成的第j+1个点向第j个点连一条边权为1的边
那么i->j有一条边权为k的边等价于i向j拆成的第k个点连边
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 100 #define MOD 2009 #define P(i,j) (((j)-1)*m+(i)) using namespace std; struct Matrix{ int xx[M][M]; Matrix() { memset(xx,0,sizeof xx); } int* operator [] (int x) { return xx[x]; } }a,map; int n,m,t; void operator *= (Matrix &x,Matrix &y) { int i,j,k; Matrix z; for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(k=1;k<=n;k++) z[i][j]+=x[i][k]*y[k][j],z[i][j]%=MOD; x=z; } void Quick_Power(int y) { static Matrix x=map; while(y) { if(y&1)a*=x; x*=x; y>>=1; } } int main() { int i,j,x,last; cin>>m>>t;n=m*9; for(i=1;i<=m;i++) for(j=2;j<=9;j++) map[P(i,j)][P(i,j-1)]=1; for(i=1;i<=m;i++) for(j=1;j<=m;j++) { scanf("%1d",&x); if(x==0) continue; map[i][P(j,x)]=1; } for(i=1;i<=n;i++) a[i][i]=1; Quick_Power(t); printf("%d\n",a[1][m]); return 0; }
BZOJ 1297 SCOI2009 迷路 矩阵乘法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。