题意:

给出一棵树,再给出每个节点上的值(一个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. java中静态代理跟动态代理之间的区别

    文章转载于:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另 ...

  2. x11vnc

    http://cisight.com/how-to-setup-vnc-server-remote-desktop-in-ubuntu-11-10-oneiric/ Install VNC serve ...

  3. MMU和TLB

    MMU和TLB 记得那家芯片公司给我电话面试的时候,别的都还好,可是他问我什么是MMU,我只能干瞪眼.今天在看<Linux内核源码(陈莉君)>的时候,无意中看到第二章内存地址这一节,学习如 ...

  4. Objective-C:三种文件导入的方式以及atomic和nonatomic的区别

    一.三种文件导入的方式比较:   类的前项声明@class.import.include: 1.采用@class 类名的方式,它会告诉编译器有这么一个类,目前不需要知道它内部的实例变量和方法是如何定义 ...

  5. tomcat manager app 和 host maganger

    当你以为你了解某个东西时,其实你不了解它.比如tomcat也可以像jboss一样有用户名和密码 就在apache-tomcat-8.0.21\conf\tomcat-users.xml里配置用户名和密 ...

  6. POJ 1903 & ZOJ 2469 & UVA 1326 Jurassic Remains (部分枚举)

    题意:给定n个只有大写字母组成的字符串,选取尽可能多的字符串,使得这些字符串中每个字母的个数都是偶数.n<=24 思路:直接枚举每个字符串的选或不选,复杂度是O(2^n).其实还有更简便的方法. ...

  7. 《Linux内核设计与实现》读书笔记 - 目录 (完结)【转】

    转自:http://www.cnblogs.com/wang_yb/p/3514730.html 读完这本书回过头才发现, 第一篇笔记居然是 2012年8月发的, 将近一年半的时间才看完这本书(汗!! ...

  8. Lucene学习笔记(更新)

    1.Lucene学习笔记 http://www.cnblogs.com/hanganglin/articles/3453415.html    

  9. SQL注入实验,PHP连接数据库,Mysql查看binlog,PreparedStatement,mysqli, PDO

    看到有人说了判断能否sql注入的方法: 简单的在参数后边加一个单引号,就可以快速判断是否可以进行SQL注入,这个百试百灵,如果有漏洞的话,一般会报错. 下面内容参考了这两篇文章 http://blog ...

  10. getHitRect获取点击控件的位置

    public  void getHitRect(Rect outRect)                   Added in API level 1 Hit rectangle in parent ...