传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1297
当图的边带上了权值,我们怎么办?没错,拆点,将每个点拆成9个点,对应1~9的边权,就轻松解决了。。。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define rep(i, n) for(int i = 0; i < n; i ++)
const int maxn = 110;
const int mod = 2009;
char c[maxn][maxn];
struct Matrix {
int a[maxn][maxn];
int l, w;
Matrix() {
l = w = 0;
memset(a, 0, sizeof(a));
}
Matrix operator * (Matrix t) {
Matrix tt;
tt.l = l; tt.w = t.w;
rep(i, l) rep(j, t.w) rep(k, w) {
tt.a[i][j] = (tt.a[i][j] + a[i][k] * t.a[k][j]) % mod;
}
return tt;
}
}ans, res;
int n, t;
void mi(int l) {
while(l) {
if(l & 1) res = res * ans;
ans = ans * ans;
l >>= 1;
}
return;
}
int main() {
scanf("%d%d", &n, &t);
ans.l = ans.w = res.l = res.w = n * 9;
rep(i, n * 9) res.a[i][i] = 1;
rep(i, n) {
scanf("%s", c[i]);
rep(j, n) {
if(c[i][j] != '0') {
ans.a[i * 9 + 8][j * 9 + 9 - (int)(c[i][j] - '0')] = 1;
}
}
}
rep(i, n) rep(j, 8) ans.a[i * 9 + j][i * 9 + j + 1] = 1;
mi(t);
printf("%d\n", res.a[8][n * 9 - 1]);
return 0;
}