CodeForces 919D Substring 拓扑排序+dp

62 篇文章 0 订阅

D. Substring

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a graph with nn nodes and mm 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 33. Your task is find a path whose value is the largest.

Input

The first line contains two positive integers n,mn,m (1≤n,m≤3000001≤n,m≤300000), denoting that the graph has nn nodes and mm directed edges.

The second line contains a string ss with only lowercase English letters. The ii-th character is the letter assigned to the ii-th node.

Then mm lines follow. Each line contains two integers x,yx,y (1≤x,y≤n1≤x,y≤n), describing a directed edge from xx to yy. Note that xx can be equal to yy and there can be multiple edges between xx and yy. 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

Copy

-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→3→4→5 1→3→4→5. The value is 33 because the letter 'a' appears 33 times.

 


题意:

       给你一个长度为n的字符串,第i个字符代表第i个结点的字符,现在给你m条单向边。一条路径的权值大小是这条路上出现次数最多的字母的出现次数,即假设有一条路径为经过的结点上的字母为a\rightarrow b\rightarrow a\rightarrow b\rightarrow a,则这条路径的权值为3,因为出现次数最多的为a,出现三次,现在要求你找出一条权值最大的路,如果存在一条权值最大的为定值的路,输出该权值,如果最大值可以为任意值,则输出-1

 

做法:

     很明显,如果出现了强连通分量,那么一定输出-1,所以一开始我还想用tarjan来做,可是后来就不知道怎么处理了,看了大神的题解才突然想起来拓扑排序,已经很久没有碰到要用这个知识点做的题目了,所以一下子还真的没想到,虽然有应该从入度为0的点开始跑这样的想法。这道题就是拓扑排序加上dp,dp[i][j]代表到达第i个结点时候经过了第j个字母的最大次数。其他的应该也不用解释了,知道是拓扑+dp之后应该挺好做了的。


#include<queue>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=300005;
int cnt,head[maxn],n,m,now;
int in[maxn],dp[maxn][26];
char s[maxn];
vector<int> ans;
struct node{
    int to,next;
}e[maxn*2];
void add(int u,int v){
    e[cnt].to=v;
    e[cnt].next=head[u],head[u]=cnt++;
}
void init(){
    memset(head,-1,sizeof(head));
    cnt=0;
}
int topo(){
    queue<int> q;
    int now=0;
    for(int i=1;i<=n;i++){
        if(!in[i]){
            q.push(i);
            dp[i][s[i]-'a']++;
        }
    }
    while(!q.empty()){
        int u=q.front(); q.pop();
        now++;
        for(int i=head[u];~i;i=e[i].next){
            int t=e[i].to,add=s[t]-'a';
            for(int j=0;j<26;j++){
                dp[t][j]=max(dp[t][j],dp[u][j]+(j==add?1:0));
            }
            if(--in[t]==0){
                q.push(t);
            }
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<26;j++)
            ans=max(ans,dp[i][j]);
    }
    if(now!=n) return -1;
    return ans;
}
int main(){
    init();
    int x,y;
    scanf("%d%d%s",&n,&m,s+1);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        add(x,y);
        in[y]++;
    }
    printf("%d\n",topo());
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值