hdu 5807 Keep In Touch

题目描述

http://acm.hdu.edu.cn/showproblem.php?pid=5807

Solution

我们令 $f[u][v][w]$ 表示从 $(u,v,w)$ 出发的方案数

则转移是 $O(n^3)$ 的,这样总的时间复杂度为 $O(n^6)$

所以我们考虑一次只走一个点,这样时间复杂度可以优化到 $O(n^4)$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 61
using namespace std;

const int p = 998244353;

int n, m, k, q, a[maxn];

int g[maxn][maxn];

int f[maxn][maxn][maxn][3];
int dfs(int u, int v, int w, int cnt) {
if (~f[u][v][w][cnt]) return f[u][v][w][cnt];
int s = 0;
for (int i = 1; i <= n; ++i) {
if (!cnt) {
if (!g[u][i]) continue;
s = (s + dfs(i, v, w, 1)) % p;
}
else if (cnt == 1) {
if (!g[v][i] || abs(a[i] - a[u]) > k) continue;
s = (s + dfs(u, i, w, 2)) % p;
}
else {
if (!g[w][i] || abs(a[i] - a[u]) > k || abs(a[i] - a[v]) > k) continue;
s = (s + dfs(u, v, i, 0)) % p;
}
}
return f[u][v][w][cnt] = s + (!cnt);
}

void init() {
memset(f, -1, sizeof f); memset(g, 0, sizeof g);
}

void work() {
cin >> n >> m >> k >> q; init();
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= m; ++i) {
int x, y; cin >> x >> y;
g[x][y] = 1;
}
for (int i = 1; i <= q; ++i) {
int x, y, z; scanf("%d%d%d", &x, &y, &z);
printf("%d\n", dfs(x, y, z, 0));
}
}

int main() {
int T; cin >> T;
while (T--) work();
return 0;
}