G - How many ways??
阿新 • • 發佈:2020-07-21
構造矩陣,用於轉移走一步的情況。
若\(i\)能走到\(j\),則\(g[j][i]=1\),否則為\(0\)
然後一開始只有\(A\)點累計有一種走法。
所以最後計算矩陣的\(k\)次方,輸出\(g[B][A]\)即可。
#include<bits/stdc++.h> using namespace std; const int mod = 1000; int n,m; struct jz{ int g[25][25]; void init(){ memset(g,0,sizeof(g)); } void one(){ memset(g,0,sizeof(g)); for(int i = 1; i <= n; ++ i) g[i][i] = 1; } }; jz operator * (jz a,jz b){ jz c; c.init(); for(int i = 1; i <= n; ++ i) for(int j = 1; j <= n; ++ j) for(int k = 1; k <= n; ++ k) c.g[i][j] += a.g[i][k] * b.g[k][j] % mod, c.g[i][j] %= mod; return c; } jz ksm(jz x,int y){ jz z; z.one(); while(y){ if(y & 1) z = z * x; y >>= 1; x = x * x; } return z; } jz mp,p; int main(){ while(scanf("%d%d",&n,&m)){ if(n == 0 && m == 0) break; mp.init(); for(int i = 1; i <= m; ++ i){ int x,y; scanf("%d%d",&x,&y); ++ x; ++ y; mp.g[y][x] = 1; } int T; scanf("%d",&T); while(T --){ int s,t,k; scanf("%d%d%d",&s,&t,&k); ++ s; ++ t; p = ksm(mp,k); printf("%d\n",p.g[t][s]); } } return 0; }