题意:

  给一棵n节点的树图,每个点都是一个小写字母,要求找到两个点(a,b),从a->b的路径上形成了一个字符串为s。给出s,问是否存在这样的点对。

思路:

  考虑一个点,要么从该点出发,要么在该点结束,要么它作为一个中间点将左右两个串连起来成为s。叶子只能是起点或者终点。在每个点中需要保存两个队列,表示有点可以从正or反向走到这个点的长度(即前缀与后缀,但只需记录当前点是排在第几)。对于在本节点连接的情况,枚举一下哪些孩子可能在本节点连接就行了。

  2s多

 #include <bits/stdc++.h>
#define pii pair<int,int>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
struct node
{
int from, to, next;
node(){};
node(int from,int to,int next):from(from),to(to),next(next){};
}edge[N*]; int head[N], edge_cnt, n, m;
char c[N], s[N];
void add_node(int from,int to)
{
edge[edge_cnt]=node(from,to,head[from]);
head[from]=edge_cnt++;
} bitset<> mapp[N], mapp2[N];
deque<int> que1[N], que2[N];
bool ans;
void DFS(int t,int far)
{
node e;
for(int i=head[t]; i!=- && ans==false; i=e.next)
{
e=edge[i];
if(e.to==far) continue;
DFS(e.to, t); int siz=que1[e.to].size();
for(int j=; j<siz; j++) //将que1装进来先
{
int r=que1[e.to].front();
que1[e.to].pop_front();
que1[e.to].push_back(r); //que1[e.to]并没有删除
if( c[t]==s[r+] )
{
if(mapp[t][r+]) mapp2[t][r+]=; //增加1个位表示是否有两个孩子能连到此点
else if(!mapp[t][r+]) mapp[t][r+]=,que1[t].push_back(r+);
if(r+==m)
{
ans=true;
return ;
}
}
}
} for(int i=head[t]; i!=- && ans==false; i=e.next) //考虑每个孩子
{
e=edge[i];if(e.to==far) continue; int siz=que1[e.to].size(); //先把此孩子的左,从mapp中全部去掉
for(int j=; j<siz; j++)
{
int r=que1[e.to].front();
que1[e.to].pop_front();
que1[e.to].push_back(r);
if( c[t]==s[r+] && !mapp2[t][r+] ) mapp[t][r+]=;
} siz=que2[e.to].size(); //判断是否在此点链接
for(int i=; i<siz; i++)
{
int r=que2[e.to].front();
que2[e.to].pop_front();
que2[e.to].push_back(r); //que2还没有删
if( mapp[t][r-]== ){ ans=true; return ;} //找到了另一半
} while( !que2[e.to].empty() ) //找不到时,再将que2装进去
{
int r=que2[e.to].front();que2[e.to].pop_front();
if( c[t]==s[r-] ) //刚好相同
{
que2[t].push_back( r- );
if(r-==) //以此点为终点
{
ans=true;
return ;
}
}
} while( !que1[e.to].empty() ) //将此孩子的que1装回去
{
int r=que1[e.to].front();
que1[e.to].pop_front();
if( c[t]==s[r+] )
{
if( !mapp[t][r+] ) mapp[t][r+]=;
}
}
}
if(c[t]==s[]) que1[t].push_back(); //起点或终点
if(c[t]==s[m]) que2[t].push_back(m);
} bool test() //s的长度为1的情况
{
for(int i=; i<=n; i++)
if(c[i]==s[]) return true;
return false;
} void init()
{
edge_cnt=;
ans=false;
memset(head,-,sizeof(head));
for(int i=; i<=n; i++)
mapp[i].reset(),
mapp2[i].reset(),
que1[i].clear(),
que2[i].clear();
} int main()
{
//freopen("input.txt", "r", stdin);
int t, a, b, Case=;
cin>>t;
while(t--)
{
scanf("%d",&n);
init();
for(int i=; i<n; i++)
{
scanf("%d%d",&a,&b);
add_node(a,b);
add_node(b,a);
}
scanf("%s", c+);
scanf("%s", s+);
m=strlen(s+); DFS(,-);
if(m==)
{
if( test() ) printf("Case #%d: Find\n", ++Case);
else printf("Case #%d: Impossible\n", ++Case);
}
else if(m<=n&&ans==true)printf("Case #%d: Find\n", ++Case);
else printf("Case #%d: Impossible\n", ++Case);
}
return ;
}

AC代码

HDU 5469 Antonidas (树形DP,暴力)的更多相关文章

  1. hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)

    题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...

  2. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  3. 【BZOJ3696】化合物 树形DP+暴力

    [BZOJ3696]化合物 Description 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题.    这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏.这个游戏很蛋疼 ...

  4. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  5. hdu 6201 【树形dp||SPFA最长路】

    http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...

  6. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  7. hdu 4081 最小生成树+树形dp

    思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...

  8. HDU 3899 简单树形DP

    题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...

  9. HDU 4714 Tree2cycle (树形DP)

    题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定 ...

  10. hdu Anniversary party 树形DP,点带有值。求MAX

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

随机推荐

  1. Tautonym Puzzle

    题意: 构造一个长度不超过200,数字不大于100的序列,使得合法子序列的个数恰好为N: 合法子序列是指一个长度为偶数的序列,前一半和后一半相等. 解法: 考虑这种构造方法 假设我们当前有序列为 $x ...

  2. A - Alyona and Numbers

    Description After finishing eating her bun, Alyona came up with two integers n and m. She decided to ...

  3. 前端HTML 与css 整理(未完)

    HTML 中的标签存放于文本文件中 需要按照以下固定的文档结构组织:<!DOCTYPE HTML><html> <head>头部相关信息 </head> ...

  4. LeetCode:104 Maximum Depth of Binary Tree(easy)

    题目: Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the ...

  5. Axure RP 7.0 标准教程(2)--基本介绍

    母版:用来放置一些相同元素的部件  两个页面都放入母版   一处更改 所有更改 添加图片:双击可以本地添加 ---------- 创建share.axure账号  https://share.axur ...

  6. java保留小数位数

    System.out.println(String.format("%.5f",new Main().minRadius(n,m)));

  7. 洛谷P3338 [ZJOI2014]力(FFT)

    传送门 题目要求$$E_i=\frac{F_i}{q_i}=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^n\frac{q_j}{(j-i)^2}$ ...

  8. [Xcode 实际操作]二、视图与手势-(7)UIView视图的渐变填充

    目录:[Swift]Xcode实际操作 本文将演示创建一个具有渐变填充色的图形 import UIKit class ViewController: UIViewController { overri ...

  9. 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:4. 设备上报属性

    文档目录: 说明 1. 连接阿里云物联网 2. IoT 客户端 3. 订阅Topic与响应Topic 4. 设备上报属性 4.1 上报位置信息 5. 设置设备属性 6. 设备事件上报 7. 服务调用 ...

  10. Redis - Windows平台下怎么切换db并且清理数据

    Redis 本身支持16个数据库(0~15),通过 数据库id 设置,默认为0.在Windows平台下可以通过启动redis-cli.exe来进入客户端,客户端默认连接数据库0,在客户端里可以输入各种 ...