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≤300000), 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.
Sample Input
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
Hint
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.
题意:给你n个点,m条边,每个点都表示一个字母,一条路的权值是路上最多的那个字母字母的个数,求权值最大的路的权值,如果图存在环则输出-1
思路:用拓扑序的方式去遍历每条通路,对每个点到下一个点,纪录一下每个字母最大值,最后看最大值就好了
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
#include<queue>
#include<set>
using namespace std;
#define maxn 400000
int head[maxn],a[maxn],ans[maxn][30],cnt,in[maxn];int n,m;
struct Edge
{
int to,next;
}edge[maxn];
void addedge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
in[v]++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(in,0,sizeof(in));
memset(ans,0,sizeof(ans));
cnt=0;
}
char b[maxn];
int slove()
{
int max1=-1,sum=n;
queue<int>q;
for(int i=1;i<=n;i++)
{
if(!in[i]) {
q.push(i);
ans[i][a[i]]++;
}
}
while(!q.empty())
{
int st=q.front();
q.pop();
sum--;
for(int i=head[st];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
for(int j=1;j<=26;j++)
{
if(j==a[v])ans[v][j]=max(ans[v][j],ans[st][j]+1);
else ans[v][j]=max(ans[v][j],ans[st][j]);
max1=max(max1,ans[v][j]);
}
in[v]--;
if(!in[v]) q.push(v);
}
}
if(sum==0) return max1;
else return -1;
}
int main()
{
scanf("%d %d",&n,&m);
scanf("%s",b+1);
init();
for(int i=1;b[i]!='\0';i++)
{
a[i]=b[i]-'a'+1;
}
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
addedge(u,v);
}
printf("%d\n",slove());
}