题意:有向图,如果图有环输出-1,否则输出最优解,最优解是路径最长值,而路径最长值的定义是,这条路径上出现频数最多的字母个数。
思路:拓扑排序加dp,时间复杂度是26*n。唯一需要注意的点是,在转移过程中需要判断是否由当前父节点转移,是才加一,否则,不加一。如果不这样,就会造成重复加。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e5+100;
char a[maxn];
int dp[maxn][30],d[maxn],n,m;
vector<int>G[maxn];
void top()
{
queue<int>q;
for(int i=1;i<=n;i++)if(!d[i])q.push(i),dp[i][a[i]-'a'] = 1;
while(!q.empty())
{
int u = q.front();
q.pop();
for(auto v : G[u])
{
for(int i=0;i<26;i++)dp[v][i] = max(dp[u][i],dp[v][i]);
int i = a[v]-'a';
if(dp[v][i] == dp[u][i])dp[v][i] += 1;
d[v]--;
if(!d[v])q.push(v);
}
}
for(int i=1;i<=n;i++)
{
if(d[i])
{
puts("-1");
return ;
}
}
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<<'\n';
}
int main()
{
cin>>n>>m>>a+1;
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
d[v]++;
}
top();
}