题解:P12742 [POI 2016 R3] 信使 Messenger
Claire0918 · · 题解
建议先看 P8502。
我们考虑设
每次转移完成后将
答案还要求途中不经过
求
按上述式子转移即可,时间复杂度
Code:
#include<bits/stdc++.h>
#define mem(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 100 + 10, maxd = 50;
int n, m, mod, q;
int f[maxn][maxn][maxd + 10], g[maxn][maxn][maxd + 10], h[maxn][maxn][maxd + 10];
vector<int> a[maxn];
template<typename Tp_x, typename Tp_y>
inline int mod_add(Tp_x x, Tp_y y){
return x += y, x >= mod ? x -= mod : x;
}
template<typename Tp_x, typename Tp_y>
inline int self_mod_add(Tp_x &x, Tp_y y){
return x = mod_add(x, y);
}
template<typename Tp, typename... Arg>
inline int mod_add(Tp x, Arg ...args){
return x += mod_add(args...), x >= mod ? x -= mod : x;
}
int main(){
scanf("%d %d %d", &n, &m, &mod);
for (int i = 1; i <= m; i++){
int u, v;
scanf("%d %d", &u, &v), a[u].push_back(v);
}
for (int i = 1; i <= n; i++){
f[i][i][0] = h[i][i][0] = 1;
for (int j = 1; j <= n; j++){
g[i][j][0] = 1;
}
}
for (int i = 1; i <= maxd; i++){
for (int u = 1; u <= n; u++){
for (auto v: a[u]){
for (int j = 1; j <= n; j++){
self_mod_add(f[j][v][i], f[j][u][i - 1]);
}
}
}
for (int j = 1; j <= n; j++){
for (int k = 1; k <= n; k++){
h[j][k][i] = f[j][k][i], g[j][k][i] = f[j][j][i];
for (int x = 1; x < i; x++){
self_mod_add(h[j][k][i], mod - (long long)f[j][k][x] * g[k][j][i - x] % mod);
self_mod_add(g[j][k][i], mod - (long long)f[j][k][x] * h[k][j][i - x] % mod);
}
}
}
for (int j = 1; j <= n; j++){
f[j][j][i] = 0;
}
}
scanf("%d", &q);
while (q--){
int x, y, d;
scanf("%d %d %d", &x, &y, &d), printf("%d\n", h[x][y][d]);
}
return 0;
}