Codeforces 919D:Substring(拓扑排序+DP)

D. Substring

time limit: per test3 seconds

memory limit: per test256 megabytes

inputstandard: input

outputstandard: output

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

Input

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

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

Then m lines follow. Each line contains two integers x,y(1≤x,y≤n)x,y (1≤x,y≤n)x,y(1≤x,y≤n), describing a directed edge from xxx to yyy. Note that xxx can be equal to yyy and there can be multiple edges between xxx and yyy. 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-1−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→51→3→4→51→3→4→5. The value is 333 because the letter ‘a’ appears 333 times.

题意

给出有nnn个点和mmm条边的有向图,每个节点上有一个小写字母,求所有通路中出现次数最多的字母出现的次数,如果出现了无数次,输出−1-1−1

Solve

用拓扑排序判断图中是否有环,如果有环,那么环上的字母出现的次数为无限多次,输出−1-1−1。

如果能够进行拓扑排序,对于每次遍历的节点,更新当前路上字母出现次数的最大值

dp[i][j]dp[i][j]dp[i][j]表示到达节点iii,字母′a′+j'a'+j′a′+j出现的最大次数

Code

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x7f7f7f7f
const int maxn=1e6+10;
const int mod=1e9+7;
using namespace std;
int n,m;
char ch[maxn];
int visi[maxn];
// dp[i][j]表示到i位置,字母j出现的最多次数
int dp[maxn][50];
int cnt;
vector<int>v[maxn];
queue<int>que;
void topo()
{
for(int i=1;i<=n;i++)
if(!visi[i])
{
que.push(i);
dp[i][ch[i]-'a']++;
}
while(!que.empty())
{
cnt++;
int res=que.front();
que.pop();
int sz=v[res].size();
for(int i=0;i<sz;i++)
{
visi[v[res][i]]--;
if(!visi[v[res][i]])
que.push(v[res][i]);
for(int j=0;j<26;j++)
dp[v[res][i]][j]=max(dp[v[res][i]][j],dp[res][j]+(ch[v[res][i]]-'a'==j));
}
}
if(cnt<n)
cout<<-1<<endl;
else
{
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<26;j++)
ans=max(ans,dp[i][j]);
}
cout<<ans<<endl;
}
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
cin>>(ch+1);
ms(visi,0);
int x,y;
for(int i=0;i<m;i++)
{
cin>>x>>y;
v[x].push_back(y);
visi[y]++;
}
topo();
return 0;
}
上一篇:xcode插件种类


下一篇:CF Fox And Names (拓扑排序)