首页 > 学院 > 开发设计 > 正文

Codeforces Gym 100962 J. Jimi Hendrix

2019-11-08 02:32:29
字体:
来源:转载
供稿:网友

Description

You are given a tree T consisting of n vertices and n−1 edges. Each edge of the tree is associated with a lowercase English letter ci. You are given a string s consisting of lowercase English letters. Your task is to nd a simple path in the tree such that the string formed by concatenation of letters associated with edges of this path contains string s as a subsequence, or determine that there exists no such simple path.

Input

The rst line of input contains two positive integers n and m (2≤n≤5×105,1≤m≤n−1), the number of vertices in the tree and the length of the string s. The following n−1 lines contain triples ui,vi,ci (1≤ui,vi≤n,ui≠vi,ci is a lowercase English letter), denoting an edge (ui,vi) associated with letter ci. The last line contains a string s (∣s∣=m) consisting of lowercase English letters.

Output

If the desired path exists, output its endpoints a and b. Otherwise, output -1 -1. If there are several possible answers, you are allowed to output any of them.

题意

给定 G = (V, E) , |E| = |V|-1 的树。树上直接相连两点间的边上记录一个字符 ci 。树上 a 点到 b 点的路径经过的边构成一个字符串,假设为 T 。问给定一个长为 m 的字符串 S ,S 能否成为某个 T 的子序列,如果可以,给出构成 T 串的两个端点 a b。否则输出 -1 -1

分析

貌似已经搞不清此题的算法,感觉算是树分治的问题,但又有最优化问题的思想。

此题的关键在于维护以某点为根的子树的最优状态。

dp[i].lenl 表示以点 i 为根的子树最长已经匹配了 S 串的串首 lenl 个元素,同时匹配这 lenl 个元素的起始点为 idxl 。

dp[i].lenr 表示以点 i 为根的子树最长已经匹配了 S 串的串尾 lenr 个元素,同时匹配这 lenr 个元素的结束点为 idxr 。

任意取一个点作为树的根,跑一遍 dfs 。若在某点最终 dp[i].lenl + dp[i].lenr >= m 且取到这么多元素不止点 i 的同一子树内,则有解。

代码

#include<bits/stdc++.h>using namespace std;const int maxn = 5e5 + 10;int n, m;char ch, s[maxn];vector< pair<int, char> > g[maxn];struct Node{ int lenl, lenr, idxl, idxr;}dp[maxn];bool dfs(int rt, int fa){ for(int i=0, to;i<g[rt].size();i++) { to = g[rt][i].first; if(to == fa) continue; if(dfs(to, rt)) return true; int tmpl = s[ dp[to].lenl + 1 ] == g[rt][i].second ? dp[to].lenl+1 : dp[to].lenl; int tmPR = s[ m - dp[to].lenr ] == g[rt][i].second ? dp[to].lenr+1 : dp[to].lenr; if(tmpl + dp[rt].lenr >= m) { printf("%d %d",dp[to].idxl, dp[rt].idxr); return true; } if(tmpr + dp[rt].lenl >= m) { printf("%d %d",dp[rt].idxl, dp[to].idxr); return true; } if(tmpl > dp[rt].lenl) { dp[rt].lenl = tmpl; dp[rt].idxl = dp[to].idxl; } if(tmpr > dp[rt].lenr) { dp[rt].lenr = tmpr; dp[rt].idxr = dp[to].idxr; } } return false;}int main(){ scanf("%d %d",&n,&m); for(int i=1, u, v;i<n;i++) { scanf("%d %d %c",&u,&v,&ch); dp[i].lenl = dp[i].lenr = 0; dp[i].idxl = dp[i].idxr = i; g[u].push_back(make_pair(v, ch)); g[v].push_back(make_pair(u, ch)); } dp[n].lenl = dp[n].lenr = 0, dp[n].idxl = dp[n].idxr = n; scanf(" %s",s+1); if(!dfs(1, -1)) printf("-1 -1");}
上一篇:八皇后

下一篇:排队接水

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表