(矩阵快速幂)hdu2157 How many ways??

来源:互联网 发布:九九乘法表js编程 编辑:程序博客网 时间:2024/06/09 23:27

题意大概是给出一个图的邻接矩阵,求出从a点走到b点长度恰好为k的路的条数。很基础的离散数学知识,这种路的条数即是邻接矩阵乘k次幂后对应位置a[i][j]的值,只不过数据范围较大,需要用矩阵快速幂来实现。其实是套模板稍加修改就可以过的一道题,但因为刚接触,天生愚钝,WA了无数次调了一个多小时才勉强ac,伤不起......

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int mod = 1000;const int maxn = 20;const int maxm = 100;int n, m, T, A, B, k;struct mat {    ll a[maxn][maxn];    mat() {        memset(a, 0, sizeof(a));    }};void print(mat ans) {    for(int i = 0;i < n;i++) {        for(int j = 0;j < n;j++)            printf("%d ", ans.a[i][j]);        printf("\n");    }    return;}mat init0() {    mat tt;    for(int i = 0;i < n;i++)        for(int j = 0;j < n;j++) tt.a[i][j] = 0;    return tt;}mat init1() {    mat tt;    for(int i = 0;i < n;i++)        for(int j = 0;j < n;j++) tt.a[i][j] = (i==j);    return tt;}mat mul(mat x, mat y) {    mat tt;    for(int i = 0;i < n;i++) {        for(int j = 0;j < n;j++) {            tt.a[i][j] = 0;            for(int k = 0;k < n;k++) {                tt.a[i][j] += x.a[i][k] * y.a[k][j];            }            tt.a[i][j] %= mod;        }    }    return tt;}mat power(mat tt, int b) {    mat res = init1();    while(b) {        if(b & 1) {            res = mul(res, tt);        }        b >>= 1;        tt = mul(tt, tt);    }    return res;}int main() {    while(scanf("%d %d", &n, &m) != EOF && (n||m)) {        int l, r;        mat gra = init0();        for(int i = 0;i < m;i++) {            scanf("%d %d", &l, &r);            gra.a[l][r] = 1;        }        scanf("%d", &T);        while(T--) {            scanf("%d %d %d", &A, &B, &k);            mat b = power(gra, k);            printf("%d\n", b.a[A][B]);        }    }    return 0;}


原创粉丝点击