CodeForces 919D Substring

Description

You are given a graph with \(n\) nodes and \(m\) directed edges. One lowercase letter is assigned to each node. We define a path's value as the number of the most frequently occurring letter. For example, if letters on a path are "abaca", then the value of that path is \(3\). Your task is find a path whose value is the largest.

Input

The first line contains two positive integers \(n, m \left(1\le n,m \le 300000\right)\), denoting that the graph has \(n\) nodes and \(m\) directed edges.

The second line contains a string \(s\) with only lowercase English letters. The \(i\)-th character is the letter assigned to the \(i\)-th node.

Then \(m\) lines follow. Each line contains two integers \(x, y \left(1 \le x,y \le n \right)\), describing a directed edge from \(x\) to \(y\). Note that \(x\) can be equal to \(y\) and there can be multiple edges between \(x\) and \(y\). Also the graph can be not connected.

Output

Output a single line with a single integer denoting the largest value. If the value can be arbitrarily large, output -1 instead.

Examples

Input

5 4
abaca
1 2
1 3
3 4
4 5

Output

3

Input

6 6
xzyabc
1 2
3 1
2 3
5 4
4 3
6 4

Output

-1

Input

10 14
xzyzyzyzqx
1 2
2 4
3 5
4 5
2 6
6 8
6 5
2 10
3 9
10 9
4 6
1 10
2 8
3 7

Output

4

Note

In the first sample, the path with largest value is \(1 \rightarrow 3 \rightarrow 4 \rightarrow 5\). The value is \(3\) because the letter 'a' appears \(3\) times.

Solution

如果图中存在环,可以得到无限长的路径,所以答案为\(-1\);否则,给定的图为DAG,记忆化搜索,求出每个字母在单条路径上的最大次数,即可得到答案。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 300011;
char s[maxn];
int deg[maxn], d[maxn];
vector<int> w[maxn];
int Find(int u, int c) {
  if (d[u] != -1) return d[u];
  d[u] = 0;
  for (int v : w[u]) {
    d[u] = max(d[u], Find(v, c));
  }
  d[u] += (s[u] == c + 'a');
  return d[u];
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  scanf("%s", s + 1);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    w[u].push_back(v);
    ++deg[v];
  }
  int ct = 0;
  queue<int> que;
  for (int i = 1; i <= n; ++i) {
    if (!deg[i])
      que.push(i), ++ct;
  }
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    for (int v : w[u]) {
      if (--deg[v] == 0)
        que.push(v), ++ct;
    }
  }
  if (ct < n) {
    puts("-1");
  } else {
    int ans = 0;
    for (int c = 0; c < 26; ++c) {
      memset(d, 0xff, sizeof d);
      for (int i = 1; i <= n; ++i)
        ans = max(ans, Find(i, c));
    }
    printf("%d\n", ans);
  }
  return 0;
}

转载于:https://www.cnblogs.com/hitgxz/p/9977643.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值