【题目链接】
【算法】
设A[i][j]为走一条边,从i走到j的方案数
C[i][j]为走两条边,从i走到j的方案数,显然有 : C = A * A = A^2
C'[i][j]为走三条边,从i走到j的方案数,那么 : C' = C * A = (A * A) * A = A^3
.......
因此,要求走n条边的方案数,只需通过矩阵乘法快速幂,计算A^n就可以了
【代码】
注意,一个n阶矩阵的零次幂是n阶单位阵(对角线上的都是1,其余都是0)
#include<bits/stdc++.h> using namespace std; #define MAXN 25 const int MOD = 1000; int n,m,s,t,a,b,k; struct Matrix { int mat[MAXN][MAXN]; } c,ans; inline void multipy(Matrix &a,Matrix b) { int i,j,k; Matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { for (k = 0; k < n; k++) { ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD; } } } a = ans; } inline Matrix power(Matrix a,int n,int s) { int i,j; Matrix ans,p = a; for (i = 0; i < s; i++) { for (j = 0; j < s; j++) { ans.mat[i][j] = (i == j); } } while (n > 0) { if (n & 1) multipy(ans,p); multipy(p,p); n >>= 1; } return ans; } int main() { while (scanf("%d%d",&n,&m) != EOF) { if (!n && !m) break; memset(c.mat,0,sizeof(c.mat)); while (m--) { scanf("%d%d",&s,&t); c.mat[s][t] = 1; } scanf("%d",&t); while (t--) { scanf("%d%d%d",&a,&b,&k); ans = power(c,k,n); printf("%d\n",ans.mat[a][b]); } } return 0; }