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


    题意

    边权(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];
                    ans.a[i][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
    ", fir.a[1][pos(n)]);
        return 0;
    }
    
  • 相关阅读:
    iOS 根据生日计算生肖
    iOS 生日计算星座
    iOS App设置icon,启动图
    iOS UITextFiled基本解析
    自定义tabbaritem上的badeg
    iOS摄像头和相册-UIImagePickerController-浅析
    C++ 类型转换操作与操作符重载 operator type() 与 type operator()
    c++中的强制转换
    啊里巴巴上市--马云的励志话
    争--转任志强
  • 原文地址:https://www.cnblogs.com/hongzy/p/10358921.html
Copyright © 2020-2023  润新知