传送门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;
}