Codeforces Round #460(Div. 2) D. Substring(记忆化搜索+判环)

28 篇文章 0 订阅
24 篇文章 0 订阅

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值