首页 > 其他 > 详细

「BZOJ 1297」「SCOI 2009」迷路「矩阵乘法」

时间:2019-02-10 11:34:40      阅读:206      评论:0      收藏:0      [点我收藏+]

题意

边权\(w \in [1, 9]\)\(n\)个结点的有向图,图上从\(1\)\(n\)长度为\(d\)的路径计数,\(n \leq 10\).

题解

如果边权为\(1\)很经典,设\(f[k][i]\)表示从\(1\)\(i\),长度为\(k\)的路径条数,则\(f[k][i] = \sum_{j=1}^n f[k - 1][j] a[j][i]\)。于是可以构造初始矩阵,再乘以\(a^k\)\(a\)为图的邻接矩阵)。

现在边权不唯一,但是边权很小,可以拆点,一个点拆成\(9\)个点,\(9\)点连成一条链,如果要连出边就从最后一个点连出去,如果连入边就连到相应到点就好。

#include <algorithm>
#include <cstdio>
using namespace std;

const int N = 12;
const int M = 92;
const int mo = 2009;

struct matrix {
    int a[M][M], n, m;
    matrix operator *(const matrix & b) {
        matrix ans; ans.n = n; ans.m = b.m;
        for(int i = 1; i <= ans.n; i ++) {
            for(int j = 1; j <= ans.m; j ++) {
                ans.a[i][j] = 0;
                for(int k = 1; k <= m; k ++) {
                    (ans.a[i][j] += a[i][k] * b.a[k][j]) %= mo;
                }
            }
        }
        return ans;
    }
    friend matrix mpow(matrix a, int b) {
        matrix ans = a; b --;
        for(; b >= 1; b >>= 1, a = a * a)
            if(b & 1) ans = ans * a;
        return ans;
    }
} fir, tr;

int n, m, d;
char s[N];

int pos(int x, int y = 8) {
    return x + y * n;
}

int main() {
    scanf("%d%d", &n, &d);
    tr.n = tr.m = m = n * 9;
    for(int i = 1; i <= m; i ++)
        for(int j = 1; j <= m; j ++)
            tr.a[i][j] = 0;
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= 8; j ++)
            tr.a[pos(i, j - 1)][pos(i, j)] = 1;
        scanf("%s", s + 1);
        for(int j = 1; j <= n; j ++) {
            int w = s[j] ^ '0';
            if(w) tr.a[pos(i)][pos(j, 9 - w)] = 1;
        }
    }
    fir.n = 1; fir.m = m;
    for(int i = 1; i <= fir.m; i ++)
        fir.a[1][i] = i == pos(1) ? 1 : 0;
    fir = fir * mpow(tr, d);
    printf("%d\n", fir.a[1][pos(n)]);
    return 0;
}

「BZOJ 1297」「SCOI 2009」迷路「矩阵乘法」

原文:https://www.cnblogs.com/hongzy/p/10358921.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!