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;
}