HDOJ 5411 CRB and Puzzle (矩阵快速幂)

来源:互联网 发布:淘宝开店推广费用 编辑:程序博客网 时间:2024/05/19 09:12

题意

给出一个邻接矩阵,求走k步以内所有的路径数量。

思路

离散数学里面学的嘛,可达矩阵的k次方就是走k步时的可达矩阵,然后就转化成计算A+A2...Am
然后想到了POJ的那个经典题目,通过对m二分来求,然后疯狂TLE= =(一个log都不能多吗。。。
最后想到了以前做的某个AC自动机的题也是求这个,给原矩阵加一维然后求幂之后直接对那一维相加就可以了。

代码

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 1e3 + 10;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;int n, m;int d;struct Matrix{    LL a[100][100];    Matrix()    {        memset(a, 0, sizeof(a));    }    inline void init()    {        for (int i = 0; i < d; i++) a[i][i] = 1;    }    inline Matrix operator + (const Matrix &B)const    {        Matrix C;        for (int i = 0; i < d; i++)            for (int j = 0; j < d; j++)                C.a[i][j] = (a[i][j] + B.a[i][j]) % 2015;        return C;    }    inline Matrix operator * (const Matrix &B)const    {        Matrix C;        for(int i = 0; i < d; i++)            for(int j = 0; j < d; j++)                for(int k = 0; k < d; k++)                    C.a[i][j] = (C.a[i][j] + a[i][k] * B.a[k][j]) % 2015;        return C;    }    inline Matrix operator ^ (const int &t)const    {        Matrix res, A = (*this);        res.init();        int p = t;        while (p)        {            if (p & 1) res = res * A;            A = A * A;            p >>= 1;        }        return res;    }    void print()    {        for (int i = 0; i < d; i++)        {            for (int j = 0; j < d; j++)                printf("%d%c", a[i][j], (j == d - 1) ? '\n' : ' ');        }    }};int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    scanf("%d", &T);    while (T--)    {        scanf("%d%d", &n, &m);        Matrix mat;        d = n + 2;        for (int i = 1; i <= n; i++)        {            int k, u;            scanf("%d", &k);            while (k--)            {                scanf("%d", &u);                mat.a[i][u] = 1;            }        }        for (int i = 0; i <= n; i++)            mat.a[0][i] = 1;        mat = mat ^ m;        int num = 0;        for (int i = 0; i <= n; i++)            num = (num + mat.a[0][i]) % 2015;        printf("%d\n", num);    }    return 0;}
0 0
原创粉丝点击