Codeforces Round #460 (Div. 2): D. Substring(DAG+DP+判环)

时间:2022-12-01 05:59:52
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 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
Note

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

题意:给一个由字母代替节点的有向图,一条路径的值为出现次数最多的字母出现次数,求出路径的最大值(如果无穷大输出-1)

思路:有环就是-1,接下来就是DAG,暴力26个字母,对于当前字母x,将所有为x的节点权值设为1,其它节点权值设为0,就是一个非常简单的DP了。

代码:

 //#include "bits/stdc++.h"
#include "cstdio"
#include "map"
#include "set"
#include "cmath"
#include "queue"
#include "vector"
#include "string"
#include "cstring"
#include "time.h"
#include "iostream"
#include "stdlib.h"
#include "algorithm"
#define db double
#define ll long long
#define vec vector<ll>
#define Mt vector<vec>
#define ci(x) scanf("%d",&x)
#define cd(x) scanf("%lf",&x)
#define cl(x) scanf("%lld",&x)
#define pi(x) printf("%d\n",x)
#define pd(x) printf("%f\n",x)
#define pl(x) printf("%lld\n",x)
#define inf 0x3f3f3f3f
#define rep(i, x, y) for(int i=x;i<=y;i++)
const int N = 3e5 + ;
const int mod = 1e9 + ;
const int MOD = mod - ;
const db eps = 1e-;
const db PI = acos(-1.0);
using namespace std;
vector<int> g[N];
queue<int> q;
char s[N];
int in[N],deg[N],vis[N],f[N],val[N];
int n,m,ans;
bool cal()//判环
{
int cnt=;
for(int i=;i<=n;i++){
if(!in[i]) q.push(i),cnt++;
vis[i]=;
}
while(q.size()){
int v=q.front();
q.pop();
for(int i=;i<g[v].size();i++){
int vv=g[v][i];
in[vv]--;
if(!in[vv]) vis[vv]=,q.push(vv),cnt++;
}
}
return cnt==n;
}
void dfs(int u)//DP(DAG)
{
f[u]=val[u];
vis[u]=;
for(int i=;i<g[u].size();i++){
int v=g[u][i];
if(!vis[v]) dfs(v);
f[u]=max(f[u],f[v]+val[u]);
}
ans=max(f[u],ans);
}
int main()
{
ci(n),ci(m);
scanf("%s",s+);
for(int i=;i<m;i++){
int x,y;
ci(x),ci(y);
g[x].push_back(y);
in[y]++,deg[y]++;
}
if(!cal()) puts("-1");
else
{
for(int i=;i<;i++){
memset(vis,, sizeof(vis));
memset(f,, sizeof(f));
for(int j=;j<=n;j++){//节点赋值
if(s[j]=='a'+i) val[j]=;
else val[j]=;
}
for(int j=;j<=n;j++){
if(!deg[j]) dfs(j);
}
}
pi(ans);
}
return ;
}