题意:给定一棵树,然后每条边有一个字母,然后给定一行字符串,问你能不能从这棵树上找到,并输出两个端点。

析:树形DP,先进行递归到叶子结点,然后再回溯,在回溯的时候要四个值,一个是正着匹配的长度和端点,一个是反着匹配的长度和端点,

然后一个一个匹配,并不断更新这个长度和端点。

代码如下:

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include <cstdio>
  3. #include <string>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <iostream>
  7. #include <cstring>
  8. #include <set>
  9. #include <queue>
  10. #include <algorithm>
  11. #include <vector>
  12. #include <map>
  13. #include <cctype>
  14. #include <cmath>
  15. #include <stack>
  16. #define print(a) printf("%d\n", (a))
  17. #define freopenr freopen("in.txt", "r", stdin)
  18. #define freopenw freopen("out.txt", "w", stdout)
  19. using namespace std;
  20. typedef long long LL;
  21. typedef pair<int, int> P;
  22. const int INF = 0x3f3f3f3f;
  23. const double inf = 0x3f3f3f3f3f3f;
  24. const LL LNF = 0x3f3f3f3f3f3f;
  25. const double PI = acos(-1.0);
  26. const double eps = 1e-8;
  27. const int maxn = 5e5 + 5;
  28. const int mod = 1e9 + 7;
  29. const int dr[] = {-1, 0, 1, 0};
  30. const int dc[] = {0, 1, 0, -1};
  31. const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
  32. int n, m;
  33. const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  34. const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  35. inline int Min(int a, int b){ return a < b ? a : b; }
  36. inline int Max(int a, int b){ return a > b ? a : b; }
  37. inline LL Min(LL a, LL b){ return a < b ? a : b; }
  38. inline LL Max(LL a, LL b){ return a > b ? a : b; }
  39. inline bool is_in(int r, int c){
  40. return r >= 0 && r < n && c >= 0 && c < m;
  41. }
  42. vector<char> w[maxn];
  43. vector<int> G[maxn];
  44. int ansx, ansy;
  45. struct Node{
  46. int lans, rans;
  47. int l, r;
  48. };
  49. Node dp[maxn];
  50. char s[maxn];
  51.  
  52. bool dfs(int u, int fa){
  53. for(int i = 0; i < G[u].size(); ++i){
  54. int v = G[u][i];
  55. if(v == fa) continue;
  56. if(dfs(v, u)) return true;
  57.  
  58. int l = s[dp[v].l+1] == w[u][i] ? dp[v].l+1 : dp[v].l;
  59. int r = s[m-dp[v].r] == w[u][i] ? dp[v].r+1 : dp[v].r;
  60. if(l + dp[u].r >= m){
  61. ansx = dp[v].lans;
  62. ansy = dp[u].rans;
  63. return true;
  64. }
  65. else if(r + dp[u].l >= m){
  66. ansx = dp[u].lans;
  67. ansy = dp[v].rans;
  68. return true;
  69. }
  70. if(l > dp[u].l){
  71. dp[u].l = l;
  72. dp[u].lans = dp[v].lans;
  73. }
  74. if(r > dp[u].r){
  75. dp[u].r = r;
  76. dp[u].rans = dp[v].rans;
  77. }
  78. }
  79. return false;
  80. }
  81.  
  82. int main(){
  83. while(scanf("%d %d", &n, &m) == 2){
  84. for(int i = 1; i <= n; ++i) G[i].clear(), w[i].clear();
  85. int u, v;
  86. char ch;
  87. for(int i = 1; i < n; ++i){
  88. scanf("%d %d %c", &u, &v, &ch);
  89. dp[i].l = dp[i].r = 0;
  90. dp[i].lans = dp[i].rans = i;
  91. w[u].push_back(ch);
  92. w[v].push_back(ch);
  93. G[u].push_back(v);
  94. G[v].push_back(u);
  95. }
  96. dp[n].l = dp[n].r = 0;
  97. dp[n].lans = dp[n].rans = n;
  98.  
  99. scanf("%s", s+1);
  100. ansx = ansy = -1;
  101. dfs(1, -1);
  102. printf("%d %d\n", ansx, ansy);
  103. }
  104. return 0;
  105. }

Gym 100962J Jimi Hendrix (树形DP)的更多相关文章

  1. 树形DP Gym 100496H House of Representatives

    题目传送门 /* 题意:寻找一个根节点,求min f(u) = ∑ρ(v, u) * p(v).ρ(v, u)是u到v的距离,p(v)是v点的权值 树形DP:先从1出发遍历第一次,sum[u]计算u到 ...

  2. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  3. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  4. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  5. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  6. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  7. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  8. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

  9. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

随机推荐

  1. 【ZJOI2017 Round1练习】D2T1 river(二分图)

    题意: 思路:这道题并没有官方题解 没有羊驼在所有三元组中出现就是NO 现在考虑不少于1只的情况 删去其中一只,我们得到了两组点和一些边 我们只要判断这是否为一张二分图,使用暴力染色的方法就有60分了 ...

  2. hdu2157:How many ways??

    n<=20个点m<=100条边有向图不带权,t个询问问Ai到Bi的经过k<=20条边方案数多少. f[i][j]--i到j的方案数,,初始化成初邻接矩阵,这样做一次就得到2条路最短路 ...

  3. msp430项目编程32

    msp430中项目---电阻测量系统32                  Ad 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结

  4. java collection集合

    集合:用于存储对象的容器.集合中可以存储任意类型的对象,长度可变. 集合和数组的比较 集合和数组都是存储对象的容器,不同的是,数组可以存储基本数据类型(int.short.long.char.Bool ...

  5. Java实验--继承与多态

    ---恢复内容开始--- 题目如下: [实验任务一]:面积计算(设计型). 1. 实验要求: 实验报告中要求包括程序设计思想.程序流程图.源代码.运行结果截图.编译错误分析等内容. 2.实验内容: ( ...

  6. Maven+mybatis教程

    首先,配置maven 在eclipse中把maven路径和settings.xml文件配置好之后,否则后续会有一些问题 可以设一个环境变量M2_HOME指向你的maven安装目录 M2_HOME=G: ...

  7. Java描述符(修饰符)的类型

    以下内容引用自http://wiki.jikexueyuan.com/project/java/modifier-types.html: 描述符(修饰符)是添加到那些定义中来改变他们的意思的关键词.J ...

  8. nexus-3本地下载jar的settipng.xml配置

    打开maven安装目录下的setting.xml <servers> <server> <id>nexus</id> <username>a ...

  9. EJB学习(三)——java.lang.ClassCastException: com.sun.proxy.$Proxy2 cannot be cast to..

    在上一篇博客介绍了怎样使用使用Eclipse+JBOSS创建第一个EJB项目,在这期间就遇到一个错误: Exception in thread "main" java.lang.C ...

  10. Prime Distance(二次筛素数)

    Description The branch of mathematics called number theory is about properties of numbers. One of th ...