Codeforces Gym 100962 J. Jimi Hendrix

来源:互联网 发布:手机计步器软件排行 编辑:程序博客网 时间:2024/05/01 01:30

Description

You are given a tree T consisting of n vertices and n1 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 (2n5×105,1mn1),
the number of vertices in the tree and the length of the string s.
The following n1 lines contain triples ui,vi,ci (1ui,vin,uivi,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");}
0 0
原创粉丝点击