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

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

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

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define print(a) printf("%d\n", (a))
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 5e5 + 5;
const int mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
vector<char> w[maxn];
vector<int> G[maxn];
int ansx, ansy;
struct Node{
int lans, rans;
int l, r;
};
Node dp[maxn];
char s[maxn]; bool dfs(int u, int fa){
for(int i = 0; i < G[u].size(); ++i){
int v = G[u][i];
if(v == fa) continue;
if(dfs(v, u)) return true; int l = s[dp[v].l+1] == w[u][i] ? dp[v].l+1 : dp[v].l;
int r = s[m-dp[v].r] == w[u][i] ? dp[v].r+1 : dp[v].r;
if(l + dp[u].r >= m){
ansx = dp[v].lans;
ansy = dp[u].rans;
return true;
}
else if(r + dp[u].l >= m){
ansx = dp[u].lans;
ansy = dp[v].rans;
return true;
}
if(l > dp[u].l){
dp[u].l = l;
dp[u].lans = dp[v].lans;
}
if(r > dp[u].r){
dp[u].r = r;
dp[u].rans = dp[v].rans;
}
}
return false;
} int main(){
while(scanf("%d %d", &n, &m) == 2){
for(int i = 1; i <= n; ++i) G[i].clear(), w[i].clear();
int u, v;
char ch;
for(int i = 1; i < n; ++i){
scanf("%d %d %c", &u, &v, &ch);
dp[i].l = dp[i].r = 0;
dp[i].lans = dp[i].rans = i;
w[u].push_back(ch);
w[v].push_back(ch);
G[u].push_back(v);
G[v].push_back(u);
}
dp[n].l = dp[n].r = 0;
dp[n].lans = dp[n].rans = n; scanf("%s", s+1);
ansx = ansy = -1;
dfs(1, -1);
printf("%d %d\n", ansx, ansy);
}
return 0;
}

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. HDU 3001【状态压缩DP】

    题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数 ...

  2. Spring Cloud(8):Sleuth和Zipkin的使用

    场景: 某大型电商网站基于微服务架构,服务模块有几十个. 某天,测试人员报告该网站响应速度过慢.排除了网络问题之后,发现很难进一步去排除故障. 那么:如何对微服务的链路进行监控呢? Sleuth: 一 ...

  3. redis连接数据库进行操作

    该项目需要的类目录 1.首先我们需要创建我们的实体类 2.放置我们的dao层,在里面写入方法 3.配置类Appconfig需要加入我们的JdbcTemplate方法,因为我们用的是spring,所以需 ...

  4. Java中Cookie常用操作类(Spring中操作Cookie)

    说明:Cookie下用Key取值没有快速的方法,只能便利循环去取. 技巧:置0则cookie会立即删除,设置-1,负值则会在关闭浏览器后删除.切记一定要增加路径:setPath("/&quo ...

  5. 【网络】TCP的流量控制

    一.利用滑动窗口实现流量控制 流量控制是让发送方的发生速率不要太快,要让接收方来得及接收. 发送方的发送窗口不能超过接收方给出的接收窗口的数值,TCP的窗口单位是字节,不是报文段. TCP为每一个连接 ...

  6. dhcp 过程

    The Question SuperUser reader Sagnik Sarkar wants to know what the difference between 127.0.0.1 and ...

  7. js获取get传递的值

    <script language="javascript" src="js/jquery-1.9.0.min.js"></script> ...

  8. shell选择语句、循环语句

    判断语句:  if 判断条件  then    语句  [elif]    [语句]  ...  [else    语句]  fi    #!/bin/bash  if [ $# -eq 0 ]  t ...

  9. 遍历数据库全部表,将是datetime类型的列的值进行更新

    declare @tablename nvarchar(80)   declare @cloumn nvarchar(80)   declare @sql nvarchar(400) declare ...

  10. mysql 中 unix_timestamp和from_unixtime 时间戳函数

    1.unix_timestamp 将时间转化为时间戳.(date 类型数据转换成 timestamp 形式整数) 没传时间参数则取当前时间的时间戳 mysql> select unix_time ...