题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1297
思路
比较简单的一个矩阵快速幂的题。。。。
把每个点拆成9个点,分别代表时间1~9的状态,点i到j要t分钟,就从i的第t个状态的点向j的第1个状态的点连边权为1的边,把这个图转化成一个邻接矩阵,自乘T次即可得到答案。
代码
刚开始matrix结构体里的矩阵数组开太大了,局部开一个matrix结构体就RE了真坑爹啊。。。以后记住了
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 100 //!!!!!!
#define MOD 2009
using namespace std;
char s[MAXN];
struct Matrix
{
int num[MAXN][MAXN];
int n,m;
Matrix()
{
n=m=0;
memset(num,0,sizeof(num));
}
}map,one;
Matrix operator*(Matrix a,Matrix b)
{
Matrix c;
c.n=a.n,c.m=b.m;
for(int k=1;k<=a.m;k++)
for(int i=1;i<=c.n;i++)
for(int j=1;j<=c.m;j++)
c.num[i][j]=(c.num[i][j]+a.num[i][k]*b.num[k][j]%MOD)%MOD;
return c;
}
Matrix fastPow(Matrix base,int pow)
{
Matrix ans;
ans=one;
while(pow)
{
if(pow&1) ans=ans*base;
base=base*base;
pow>>=1;
}
return ans;
}
inline int calc(int n,int t)
{
return (n-1)*9+t;
}
int main()
{
int n,t;
scanf("%d%d",&n,&t);
one.n=one.m=map.n=map.m=calc(n,9);
for(int i=1;i<=calc(n,9);i++)
one.num[i][i]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=8;j++)
map.num[calc(i,j)][calc(i,j+1)]=1;
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=n;j++)
if(s[j]!='0')
map.num[calc(i,s[j]-'0')][calc(j,1)]=1;
}
map=fastPow(map,t);
printf("%d\n",map.num[calc(1,1)][calc(n,1)]);
return 0;
}