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 (1 ≤ n, m ≤ 300 000), 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 (1 ≤ x, y ≤ n), 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
题目大意
一个含有n 个节点m 条边的有向图,每个节点用一个小写字母表示,定义一条路径的价值为这条路径上出现的字母最多的次数,求这个最大的价值.如果价值无限大,则输出-1.
解题思路
记忆化搜索,dp[i][j]标记从i 节点开始的路径,字母j 出现的次数的最大值。
使用dp[][]=-2来标记图中是否存在环。
代码实现
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(false);\
cin.tie(0);\
cout.tie(0);
using namespace std;
#define maxn 300007
char str[maxn];
int dp[maxn][37];
struct node
{
int to;
int next;
} edge[maxn];
int head[maxn],tot;
int n,m;
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int dfs(int no,int ch)
{
if(dp[no][ch]==-2)
{
cout<<"-1"<<endl;
exit(0);
}
else if(dp[no][ch]!=-1)return dp[no][ch];
dp[no][ch]=-2;
int tmp=0;
for(int i=head[no]; i!=-1; i=edge[i].next)
{
int to=edge[i].to;
tmp=max(tmp,dfs(to,ch));
}
tmp+=(str[no-1]-'a'==ch);
return dp[no][ch]=tmp;
}
int main()
{
IO;
cin>>n>>m>>str;
memset(head,-1,sizeof head);
memset(dp,-1,sizeof(dp));
tot = 0;
for(int i=0; i<m; i++)
{
int u,v;
cin>>u>>v;
addedge(u,v);
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=0;j<26;j++)
ans=max(ans,dfs(i,j));
cout<<ans<<endl;
return 0;
}