hdu 5607 graph (矩阵乘法快速幂)
考虑一个经典的问题:
询问从某个点出发,走 k 步到达其它各点的方案数?
这个问题可以转化为矩阵相乘,所以矩阵快速幂即可解决。
本题思路:
矩阵经典问题:求从i点走k步后到达j点的方案数(mod p)。
本题输出X/Y,可以看成X是u走k步到j的方案数,Y是从u走k步的所有方案数
于是对矩阵先进行处理,即给m[i][j]乘上节点i的出度的1e9+5次方。
AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }