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 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,m(1n,m300000)n,m (1≤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 m lines follow. Each line contains two integers x,y(1x,yn)x,y (1≤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-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 13451→3→4→5. The value is 33 because the letter ‘a’ appears 33 times.

题意

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

Solve

用拓扑排序判断图中是否有环,如果有环,那么环上的字母出现的次数为无限多次,输出1-1
如果能够进行拓扑排序,对于每次遍历的节点,更新当前路上字母出现次数的最大值
dp[i][j]dp[i][j]表示到达节点ii,字母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;
}
posted @ 2019-02-14 17:00  友人-A  阅读(347)  评论(0编辑  收藏  举报