题意:
树上的每个节点都有一个字母,问有没有一条路径上的字母是目标串
思路:
从每个符合第一个字母的地方搜索
搜索分为向父节点和子节点搜,向子节点搜时必须满足子节点子树的最大深度要大于剩余的目标串长度
所以要预处理出每个节点的父节点和节点子树的最大深度
搜索的时候记录每个点是否被访问过就A,但记录路径上这个点的上一个点就T,不知道为啥....
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 10005
#define mod 1000000007
int n,m;
vector< vector<int> >v;
char target[max_];
char w[max_];
int deph[max_];
int pre[max_];
bool vis[max_];
int casnum=1;
int pre_dfs(int x,int fa)
{
pre[x]=fa;
int maxx=0;
for(int i=0;i<v[x].size();i++)
{
if(fa!=v[x][i])
{
maxx=max(pre_dfs(v[x][i],x),maxx);
}
}
deph[x]=maxx;
return maxx+1;
}
bool dfs(int x,int pos)
{
if(pos==m+1)
return true;
vis[x]=true;
if(x!=1&&vis[pre[x]]==false&&w[pre[x]]==target[pos])
{
if(dfs(pre[x],pos+1))
return true;
}
if(deph[x]<m-pos+1)
return false;
for(int i=0;i<v[x].size();i++)
{
if((vis[v[x][i]]==false)&&(w[v[x][i]]==target[pos]))
{
if(dfs(v[x][i],pos+1))
return true;
}
}
return false;
}
int main(int argc, char const *argv[]) {
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
v.clear();
v.resize(n+1);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
scanf(" %s",w+1);
scanf(" %s",target+1);
pre_dfs(1,-1);
m=strlen(target+1);
if(m>=n)
{
printf("Case #%d: Impossible\n",casnum++ );
continue;
}
int f=0;
for(int i=1;i<=n;i++)
{
if(w[i]==target[1])
{
memset(vis,false,sizeof vis);
if(dfs(i,2))
{
f=1;
break;
}
}
}
if(f)
printf("Case #%d: Find\n",casnum++ );
else
printf("Case #%d: Impossible\n",casnum++ );
}
return 0;
}