zoukankan      html  css  js  c++  java
  • Codeforces Gym100962J:Jimi Hendrix(树型DP)

    http://codeforces.com/gym/100962/attachments

    题意:有一个n个节点的字母树,给出n-1条边的信息,代表边上有一个字母,然后给出长度为m的字符串,问是否能在这棵树上找到这样一个序列等于这条字符串,输出序列的起点和终点。

    思路:用DP数组维护当到达该结点的时候,左边最长的长度是多少和达到这个长度的左端点,右边最长的长度是多少和达到这个长度的右端点。详细看代码,很容易懂。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define N 500010
     4 struct Edge {
     5     int v, nxt; char c;
     6 } edge[N*2];
     7 struct node {
     8     int l, r, ansl, ansr;
     9 } dp[N]; // l是保存头,r是保存尾的信息
    10 int tot, head[N], n, m, ansu, ansv;
    11 char s[N];
    12 
    13 void Add(int u, int v, char c) {
    14     edge[tot] = (Edge) {v, head[u], c}; head[u] = tot++;
    15     edge[tot] = (Edge) {u, head[v], c}; head[v] = tot++;
    16 }
    17 
    18 bool dfs(int u, int fa) {
    19     for(int i = head[u]; ~i; i = edge[i].nxt) {
    20         int v = edge[i].v; char c = edge[i].c;
    21         if(v == fa) continue;
    22         if(dfs(v, u)) return true; // 已经有答案了
    23         int ltmp = dp[v].l;
    24         int rtmp = dp[v].r;
    25         if(c == s[dp[v].l]) ltmp++; // 如果当前的边是左边的下一个字符
    26         if(c == s[m - dp[v].r - 1]) rtmp++; // 如果当前的边是右边的下一个字符
    27         if(ltmp + dp[u].r >= m) { // 有答案了
    28             ansu = dp[v].ansl, ansv = dp[u].ansr;
    29             return true;
    30         }
    31         if(dp[u].l + rtmp >= m) {
    32             ansu = dp[u].ansl, ansv = dp[v].ansr;
    33             return true;
    34         }
    35         if(ltmp > dp[u].l) { // 如果长度变长就更新
    36             dp[u].ansl = dp[v].ansl;
    37             dp[u].l = ltmp;
    38         }
    39         if(rtmp > dp[u].r) {
    40             dp[u].ansr = dp[v].ansr;
    41             dp[u].r = rtmp;
    42         }
    43     }
    44     return false;
    45 }
    46 
    47 int main() {
    48     scanf("%d%d", &n, &m);
    49     tot = 0; memset(head, -1, sizeof(head));
    50     for(int i = 1; i < n; i++) {
    51         int u, v; char c;
    52         cin >> u >> v >> c;
    53         Add(u, v, c);
    54         dp[i].l = dp[i].r = 0; // 点的信息
    55         dp[i].ansl = dp[i].ansr = i; // 端点答案的信息
    56     }
    57     dp[n].l = dp[n].r = 0;
    58     dp[n].ansl = dp[n].ansr = n;
    59     cin >> s;
    60     ansu = ansv = -1;
    61     dfs(1, -1);
    62     printf("%d %d
    ", ansu, ansv);
    63     return 0;
    64 }
  • 相关阅读:
    python
    python
    打开python自带IDLE出的问题
    Python GUI编程(Tkinter)8、CheckButton多选框控件
    Python GUI编程(Tkinter)7、带滚动条的Text
    Python GUI编程(Tkinter)6、Text控件
    Python GUI编程(Tkinter)5、点击按钮输出输入框中的内容
    Python GUI编程(Tkinter)4、Entry控件
    Python GUI编程(Tkinter)3、Button控件
    Python GUI编程(Tkinter)2、Label控件
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6423867.html
Copyright © 2011-2022 走看看