HDU 5469 Antonidas (树形DP,暴力)
题意:
给一棵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,暴力)的更多相关文章
- hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)
题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- 【BZOJ3696】化合物 树形DP+暴力
[BZOJ3696]化合物 Description 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题. 这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏.这个游戏很蛋疼 ...
- HDU 2196 Computer 树形DP经典题
链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...
- hdu 6201 【树形dp||SPFA最长路】
http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...
- HDU 2196 Computer 树形DP 经典题
给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...
- hdu 4081 最小生成树+树形dp
思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...
- HDU 3899 简单树形DP
题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...
- HDU 4714 Tree2cycle (树形DP)
题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定 ...
- hdu Anniversary party 树形DP,点带有值。求MAX
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
随机推荐
- Java: JavaMail 初试(一)
前言:以前的我,很喜欢写东西,写一写所想所见所闻所感,但是工作之后,总不能写出让自己满意的文章,突发奇想,能否利用写博客的时机,将其写成类似散文似的博文呢?哈哈... 邮件功能尝试:作为一个小菜鸟,对 ...
- HDOJ-1412(set)
{A} + {B} Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- STL-开篇
基本概念 STL: Standard Template Library,标准模板库 定义: c++引入的一个标准类库 特点:1)数据结构和算法的 c++实现( 采用模板类和模板函数)2)数据的存储和算 ...
- 无法打开包括文件:“SDKDDKVer.h”: No such file or directory
在已经装有Visual Studio 2010的系统中,同时安装Visual Studio 2012,安装过程很顺利,但到使用VS2013时,却出问题了. 本文主要介绍:VS中新建工程编译时出现,“无 ...
- hihocoder #1608 : Jerry的奶酪(状压DP)
传送门 题意 分析 设dp[i][j]为在i状态下当前在第j个奶酪的最小费用 转移方程:dp[(1<<k)|i][k]=dp[i][j]+d[j][k] 预处理出每个奶酪之间的距离,加入起 ...
- HDU1829【种类并查集】
题意: 检验给出条件是否有同性恋. 思路: 条件并查集. 还是一个类似的前缀和,sum[x]是x到根这段路径上的和,根一定是坐标越小的, 那么如果说对于同类(同一个集合)的判断就sum[a]是否等于s ...
- Oculus Rift, HTC Vive, SONY PSVR的全面对比
http://blog.csdn.net/xoyojank/article/details/50927572 这次有幸参加了GDC 2016, 终于把三大设备体验了个遍, 也试玩了很多不错的VR游戏. ...
- c#实现优先级队列
http://www.baidu.com/s?wd=c%23%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97&ie=utf-8&f=8& ...
- bzoj 3559: [Ctsc2014]图的分割【最小生成树+并查集】
读题两小时系列-- 在读懂题意之后,发现M(c)就是c这块最大权割边也就是的最小生成树的最大权边的权值,所以整个问题都可以在MST的过程中解决(M和c都是跟着并查集变的) 不过不是真的最小生成树,是合 ...
- 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:4.1 上报位置信息
文档目录: 说明 1. 连接阿里云物联网 2. IoT 客户端 3. 订阅Topic与响应Topic 4. 设备上报属性 4.1 上报位置信息 5. 设置设备属性 6. 设备事件上报 7. 服务调用 ...