3188 字符王国
建图,有环输出-1,无环按照拓扑序dp,设状态为 \(dp[i][j]\) 第 \(i\) 个点,\(j\) 的字符的出现的最大次数,最后遍历每个点找到最大答案。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e5+10;struct ss{int to,next;
}e[N];int n,m;
int cnt;
int head[N],in[N];
char c[N];
queue<int> q;
int dp[N][30];
void add(int u,int v){e[cnt].next=head[u];e[cnt].to=v;head[u]=cnt++;
}int main() { ios::sync_with_stdio(false);cin>>n>>m;for(int i=1;i<=n;i++){head[i]=-1;}cin>>(c+1);for(int i=1;i<=m;i++){int u,v;cin>>u>>v;add(u,v);in[v]++;}for(int i=1;i<=n;i++){if(in[i]==0){q.push(i);}}while(!q.empty()){int x=q.front();q.pop();dp[x][c[x]-'a']++;for(int i=head[x];~i;i=e[i].next){int y=e[i].to;for(int j=0;j<26;j++){dp[y][j]=max(dp[y][j],dp[x][j]);}if(--in[y]==0){q.push(y);}}}for(int i=1;i<=n;i++){if(in[i]){cout<<-1;return 0;}}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;return 0;
}