【搜索剪枝】HDU 5469 Antonidas
题意:给出1字母树,询问一字符串是否出现在该树中
思路:直接搜索剪枝,有人点分治?写了几发都T了。。有人会了教我?
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Edge { int v, nxt; Edge () { } Edge (int _v, int _n) { v = _v, nxt = _n; } }; const int MAX_N = 10007; int head[MAX_N], n, len, ecnt, Tim; char a[MAX_N], b[MAX_N]; int dis[MAX_N], f[MAX_N], vis[MAX_N]; Edge G[MAX_N << 1]; void init() { ecnt = Tim = 0; for (int i = 0; i <= n; ++i) head[i] = -1; } void add(int u, int v) { G[ecnt] = Edge(v, head[u]); head[u] = ecnt++; } void dfs(int u, int fa) { for (int i = head[u]; ~i; i = G[i].nxt) { int v = G[i].v; if (v == fa) continue; dfs(v, u); dis[u] = max(dis[u], dis[v] + 1); f[v] = u; } if (dis[u] == -1) dis[u] = 1; } bool Find(int u, int dep, int r) { vis[u] = Tim; if (dep > len) return true; if(dis[u] > r) for(int i = head[u]; ~i; i = G[i].nxt) { int v = G[i].v; if(a[v] == b[dep] && Tim != vis[v]) if(Find(v, dep + 1, r - 1)) return true; } else { if(a[f[u]] == b[dep] && Tim != vis[f[u]]) return Find(f[u], dep + 1, r - 1); } return false; } int main() { int T; scanf("%d", &T); int cas = 0; while(T--) { scanf("%d", &n); init(); int u, v; for (int i = 1; i < n; ++i) { scanf("%d%d", &u, &v); add(u, v), add(v, u); } scanf("%s%s",a + 1, b + 1); memset(dis, -1, sizeof dis); memset(vis, 0, sizeof vis); dfs(1, -1); bool f = 0; len = strlen(b + 1); for(int i = 1; i <= n; ++i) if(a[i] == b[1]) { ++Tim; if(Find(i, 2, len - 1)) { printf("Case #%d: Find\n", ++cas); f = true; break; } } if(!f) printf("Case #%d: Impossible\n", ++cas); } return 0; }