拆点。然后快速幂+矩阵。
同一个图走k次所得的解即为答案,由于路程所耗时间<10所以我们可以直接拆点。
把每个点拆为1~9个时刻。建边的时候要注意如果A->B要i分钟,那么应该在A的第i分钟和B的第1分钟连边,不然不好统计最后的解。
“1”矩阵每个点的第i时刻应该和第i+1时刻连一条边,不然快速幂中当前时刻的答案数无法被完全更新。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define mod 2009
struct matrix
{
int s[110][110];
int n;
void init(int k)
{
n=k;
memset(s,0,sizeof(s));
}
};
matrix operator *(matrix x,matrix y)
{
matrix c;
c.init(x.n);
for(int i=1;i<=c.n;i++)
{
for(int j=1;j<=c.n;j++)
{
for(int k=1;k<=c.n;k++)
{
c.s[i][j]+=x.s[i][k]*y.s[k][j];
c.s[i][j]%=mod;
}
}
}
return c;
}
matrix solve(matrix A,int k)
{
matrix res;
res.init(A.n);
for(int i=1;i<=A.n;i++)
{
res.s[i][i]=1;
}
while(k)
{
if(k&1)
res=res*A;
k>>=1;
A=A*A;
}
return res;
}
int n,T;
char st[50];
int main()
{
scanf("%d%d",&n,&T);
matrix org;
org.init(n*9);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=8;j++)
{
org.s[(i-1)*9+j][(i-1)*9+j+1]=1;
}
}
for(int i=1;i<=n;i++)
{
scanf("%s",st+1);
for(int j=1;j<=n;j++)
{
if(st[j]>'0')
{
org.s[(i-1)*9+st[j]-'0'][(j-1)*9+1]=1;
}
}
}
matrix ans;
ans=solve(org,T);
printf("%d\n",ans.s[1][n*9-8]);
return 0;
}