中文题,简而言之,一个矩阵从A 点恰好经过k个点到达B点的方案数模上1000的余数为多少。
矩阵乘法就行,优化就变成了矩阵快速幂。注意的是从A到A则k=1,题目中有重边,但考虑时当成一条就行,还有,图是有向图。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int ans[25][25][25] ;
bool had[25] ;
int n , m ;
void multi(int x , int y) {
for (int i = 0 ; i < n ; i ++) {
for (int j = 0 ; j < n ; j ++) {
for (int k = 0 ; k < n ; k ++) {
ans[x+y][i][j] += ans[x][i][k] * ans[y][k][j] ;
}
ans[x+y][i][j] %= 1000 ;
}
}
}
void pow(int k) {
int x = 1 , p = 0 ;
while (k > 0) {
if (!had[x]) {
had[x] = 1 ;
multi(x >> 1 , x >> 1) ;
}
if (k & 1) {
if (!had[p + x]) {
multi(p , x) ;
had[p + x] = 1 ;
}
p += x ;
}
x <<= 1 ;
k >>= 1 ;
}
}
int main() {
//freopen("in.txt" , "r" , stdin) ;
while (cin >> n >> m) {
if (!n && !m) break ;
memset(ans , 0 , sizeof(ans)) ;
memset(had , 0 , sizeof(had)) ;
had[0] = 1 ; had[1] = 1 ;
for (int i = 0 ; i < n ; i ++) {
ans[0][i][i] = 1 ;
}
while (m --) {
int l , r ;
cin >> l >> r ;
ans[1][l][r] = 1 ;
}
int T ;
cin >> T ;
while (T --) {
int a , b , k ;
cin >> a >> b >> k ;
if (!had[k]) pow(k) ;
cout << ans[k][a][b]%1000 << endl ;
}
}
return 0 ;
}