题意:

给出一棵树,再给出每个节点上的值(一个char字符)这些值以一个字符串s1表示,然后给出一个s2字符串,问在这棵树上是否存在两个点,从一个点走到另一个点所经过的路径上的char字符组成的字符串正好等于s1。问是否存在这么两个点。如果存在,则输出“Find”,否则,输出“Important”。

题解:

使用dfs就可以解决,但是需要进行剪枝,否则就会tle。

剪枝的方法是这样的——假设节点1是根节点,然后我们先使用一次dfs记录每个节点到叶节点的最长的路径dis[x]。

然后开始搜索,每次搜到当前点x的dis[x],如果dis[x]>剩下的字符串s1的值,那么可以走这条路,否则就不走这条路,看这个点的父节点是否满足。

上面那句话可能有些难以理解,具体来讲就是这个意思——如果从当前节点ch向它的叶节点走,需要满足的条件是从点ch到离她最远的叶节点的长度要大于剩余的未匹配的s2串的长度。如果向ch的父节点走,那么就不需要判断了(其实也可以判断,只是要么很麻烦,要么没必要,如果有即简洁又有效的方法,洗耳恭听)。

具体见代码:

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; const int N = ; struct Edge
{
int to, next;
}edge[N<<]; //前向星标,记录邻接表 int head[N], fm[N]; //节点i的edge[]下标 / 节点i的父节点
int dis[N]; //节点i到最远叶节点的长度
bool vis[N];
int n, t, k;
int len;
char s1[N], s2[N]; //源串与匹配串 void add(int u, int v)
{
edge[k].to = v;
edge[k].next = head[u];
head[u] = k++;
} void tdfs(int x)
{
int mdis = -;
for(int i = head[x]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(!vis[v])
{
vis[v] = ;
tdfs(v);
fm[v] = x;
mdis = mdis > dis[v] ? mdis : dis[v];
}
}
dis[x] = mdis == - ? : mdis+; //记录每个节点到最远的叶节点的长度
} bool dfs(int x, int disx, int mlen) //核心dfs
{
if(disx- > len) return ; //如果已匹配的长度已超过匹配串长度,即,存在这么一个串,及时返回1
if(dis[x] > mlen) //如果向叶节点走路径长度大于剩下未匹配的串的长度,则向这个方向走
{
for(int i = head[x]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(!vis[v] && s1[v] == s2[disx])
{
vis[v] = ;
if(dfs(v, disx+, mlen-)) return ;
}
}
}
if(!vis[fm[x]] && s1[fm[x]] == s2[disx]) //向父节点搜索
{
vis[fm[x]] = ;
return dfs(fm[x], disx+, mlen-);
}
return ; //都不存在,则返回0
} void init()
{
scanf("%d", &n);
k = ;
memset(head, -, sizeof(head));
for(int i = ; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
}
memset(dis, , sizeof(dis));
memset(vis, , sizeof(vis));
tdfs();
scanf("%s%s", s1+, s2+);
len = strlen(s2+)-;
} int main()
{
//freopen("test.in", "r", stdin);
scanf("%d", &t);
for(int tm = ; tm <= t; tm++)
{
init();
bool flag = ;
for(int i = ; i <= n; i++)
{
if(s1[i] == s2[])
{
memset(vis, , sizeof(vis));
if(dfs(i, , len))
{
flag = ;
break;
}
}
}
printf("Case #%d: ", tm);
if(flag) printf("Find\n");
else printf("Impossible\n");
}
return ;
}

hdu 5469 Antonidas (dfs+剪枝)2015 ACM/ICPC Asia Regional Shanghai Online的更多相关文章

  1. 【动态规划】HDU 5492 Find a path (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5492 题目大意: 一个N*M的矩阵,一个人从(1,1)走到(N,M),每次只能向下或向右走.求(N+ ...

  2. Hdu 5459 Jesus Is Here (2015 ACM/ICPC Asia Regional Shenyang Online) 递推

    题目链接: Hdu 5459 Jesus Is Here 题目描述: s1 = 'c', s2 = 'ff', s3 = s1 + s2; 问sn里面所有的字符c的距离是多少? 解题思路: 直觉告诉我 ...

  3. HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)

    Elven Postman Elves are very peculiar creatures. As we all know, they can live for a very long time ...

  4. 2015 ACM/ICPC Asia Regional Shanghai Online

    1001 Puzzled Elena 1002 Antonidas 1003 Typewriter 1004 Count the Grid 1005 Code Formatting 1006 Ther ...

  5. (并查集)Travel -- hdu -- 5441(2015 ACM/ICPC Asia Regional Changchun Online )

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 Travel Time Limit: 1500/1000 MS (Java/Others)    Memo ...

  6. (二叉树)Elven Postman -- HDU -- 54444(2015 ACM/ICPC Asia Regional Changchun Online)

    http://acm.hdu.edu.cn/showproblem.php?pid=5444 Elven Postman Time Limit: 1500/1000 MS (Java/Others)  ...

  7. 2015 ACM/ICPC Asia Regional Changchun Online HDU 5444 Elven Postman【二叉排序树的建树和遍历查找】

    Elven Postman Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  8. hdu 5444 Elven Postman(二叉树)——2015 ACM/ICPC Asia Regional Changchun Online

    Problem Description Elves are very peculiar creatures. As we all know, they can live for a very long ...

  9. HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online)

    HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online) 题目链接http://acm.hdu.edu.cn/showp ...

随机推荐

  1. AppWidget框架

    AppWidget 框架主要包括以下类: 1.AppWidgetProvider:继承自BroadcastReceiver,在AppWidget应用update.enable.disable和dele ...

  2. MDK4.6和J-LINK调试出现问题,软件自动关闭,在网上收集整理的解决办法

    MDK4.6配J-LINK调试时提示升级,升级完成后,弹出下图提示框后,软件自动退出. 提示原因:由于MDK4.6能识别山寨JLINK导致.网络牛人分析如下: 今天将Keil MDK升级到了V4.54 ...

  3. Delphi对于控件的SuperClassing(封装并扩展Button,使之变成TButton)

    写博客写了这么久,但是一直不知道应该怎么样写函数之间的调用关系和执行顺序,因为不停的跳来跳去的,但是写的时候却只能顺序写调用关系,直到今天发现这种写法很不错: TButton创建窗口是在CreateW ...

  4. Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)

    Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...

  5. OpenGL基础渲染

    客户端-服务器 客户端是存储在CPU存储器中的,并且在应用程序中执行(或者驱动程序),驱动程序将渲染命令和数据组合起来,发动到服务器执行.服务器和客户机在功能上是异步的,他们是各自独立的软件模块或者硬 ...

  6. 求1+2+…+n,要求不能使用乘除法、for、while、if、else、s witch、case 等关键字以及条件判断语句(A?B:C)和不用循环/goto/递归输出1~100的10种写法

    来源:据说是某一年某个公司的面试题 题目:求1+2+…+n, 要求不能使用乘除法.for.while.if.else.s witch.case 等关键字以及条件判断语句(A?B:C) 分析:这题本来很 ...

  7. jQuery练习二球队移动

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. PHP中对数据库操作的封装

    在动态网面设计中很多都要涉及到对数据库的操作,但是有时跟据需要而改用其它后台数据库,就需要大量修改程序.这是一件枯燥.费时而且容易出错的功作.其实我们可以用PHP中的类来实现对数据库操作的封装,从而使 ...

  9. PHP也20岁了

    当今许多世界著名的编程语言的年纪已经够大了.举个例子,PHP昨天过了生日已经20岁了,Python也24岁,HTML已经服务了22年,Ruby和JavaScript有20年,Java前段时间刚过了20 ...

  10. Android 的 init.rc 文件简介【转】

    转自:http://blog.csdn.net/yimiyangguang1314/article/details/6268177 init.rc由许多的Action和Service组成.每一个语句占 ...