51nod 3188 字符王国

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;
}

posted @ 2024-09-09 06:29  sad_lin  阅读(3)  评论(0编辑  收藏  举报