【题目链接】
【算法】
设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;
}