Step1 Problem:
给你 n 个点,m 条边的图(有向),T 次询问,对于每次询问你 A 点到 B 点走K步的路径条数(可以走重复边)。
数据范围:
0 < n <= 20, m <= 100, 1 <= T <= 100
Step2 Ideas:
我们知道 a->k 路径数 x,k->b 路径数 y,a->k->b 的路径数 x*y。
Step3 Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
const int mod = 1000;
struct node
{
int a[N][N];
};
node c, ans;
int n;
node mul(node x, node y)
{
node ans;
memset(ans.a, 0, sizeof(ans.a));
for(int k = 0; k < n; k++)
{
for(int i = 0; i < n; i++)
{
if(x.a[i][k])
for(int j = 0; j < n; j++)
{
ans.a[i][j] += x.a[i][k]*y.a[k][j];
ans.a[i][j] %= mod;
}
}
}
return ans;
}
node Pow(node x, int m)
{
node ans;
memset(ans.a, 0, sizeof(ans.a));
for(int i = 0; i < n; i++) ans.a[i][i] = 1;
while(m)
{
if(m&1) ans = mul(ans, x);
x = mul(x, x);
m >>= 1;
}
return ans;
}
int main()
{
int m, u, v, step;
while(~scanf("%d %d", &n, &m) && (n||m))
{
memset(c.a, 0, sizeof(c.a));
while(m--)
{
scanf("%d %d", &u, &v);
c.a[u][v] = 1;
}
scanf("%d", &m);
while(m--)
{
scanf("%d %d %d", &u, &v, &step);
ans = Pow(c, step);
printf("%d\n", ans.a[u][v]);
}
}
return 0;
}