hdu 5607 graph (矩阵乘法快速幂)

hdu 5607 graph (矩阵乘法快速幂)_第1张图片

 

考虑一个经典的问题:

询问从某个点出发,走 k 步到达其它各点的方案数?

这个问题可以转化为矩阵相乘,所以矩阵快速幂即可解决。

 

 

本题思路:

 

矩阵经典问题:求从i点走k步后到达j点的方案数(mod p)。

本题输出X/Y,可以看成X是u走k步到j的方案数,Y是从u走k步的所有方案数

于是对矩阵先进行处理,即给m[i][j]乘上节点i的出度的1e9+5次方。

hdu 5607 graph (矩阵乘法快速幂)_第2张图片

 

AC代码:

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<math.h>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<bitset>
11 #include<map>
12 #include<vector>
13 #include<stdlib.h>
14 using namespace std;
15 #define ll long long
16 #define eps 1e-10
17 #define MOD 1000000007
18 #define N 56
19 #define inf 1e12
20 ll n,m;
21 ll g[N];
22 struct Matrix{
23     ll m[N][N];
24 }matrix;
25 Matrix Mul(Matrix a,Matrix b){
26     Matrix res;
27     for(ll i=1;i<=n;i++){
28         for(ll j=1;j<=n;j++){
29             res.m[i][j]=0;
30             for(ll k=1;k<=n;k++){
31                 res.m[i][j]=(res.m[i][j]+(a.m[i][k]*b.m[k][j]))%MOD;
32             }
33         }
34     }
35     return res;
36 }
37 Matrix fastm(Matrix a,ll b){
38     Matrix res;
39     memset(res.m,0,sizeof(res.m));
40     for(ll i=1;i<=n;i++){
41         res.m[i][i]=1;
42     }
43     while(b){
44         if(b&1){
45             res = Mul(res,a);
46         }
47         a=Mul(a,a);
48         b>>=1;
49     }
50     return res;
51 }
52 ll pow_mod(ll a,ll b){
53     if(b==0) return 1%MOD;
54     ll tt = pow_mod(a,b>>1);
55     ll ans = tt * tt % MOD;
56     if(b&1) ans = ans * a %MOD;
57     return ans;
58     
59 }
60 int main()
61 {
62     while(scanf("%I64d%I64d",&n,&m)==2){
63         memset(g,0,sizeof(g));
64         for(ll i=0;i<m;i++){
65             ll a,b;
66             scanf("%d%d",&a,&b);
67             matrix.m[a][b]++;
68             g[a]++;
69         }
70         
71         for(ll i=1;i<=n;i++){
72             for(ll j=1;j<=n;j++){
73                 matrix.m[i][j]=(matrix.m[i][j]*(ll)pow_mod(g[i],1e9+5)%MOD)%MOD;
74             }
75         }
76         
77         ll q;
78         scanf("%I64d",&q);
79         while(q--){
80             ll u,k;
81             scanf("%I64d%I64d",&u,&k);
82             Matrix tmp = fastm(matrix,k);
83             for(ll i=1;i<=n;i++){
84                 printf("%I64d ",tmp.m[u][i]%MOD);
85             }
86             printf("\n");
87         }
88         
89     }
90     return 0;
91 }
View Code

 

你可能感兴趣的:(hdu 5607 graph (矩阵乘法快速幂))