题目地址:

http://codeforces.com/problemset/problem/919/D

题意:

首先给个图,路径上字母重复出现的最多次数,如果结果是无限大则输出 $-1$

思考:

1.首先如果存在回路,则肯定输出 $-1$

2.求解最大则需要用dp,按照拓扑排序的顺序更新节点,dp[  ][ 26 ],

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int w[300000+7];
int dp[300000+7][30];
vector<int>a[300000+7];
char s[300000+7];
void son()
{
    memset(dp,0,sizeof(dp));
    queue<int>q;
    int ct=0;
    int ans=1;
    for(int i=1;i<=n;i++)
    {
        if(w[i]==0)
        {
            dp[i][s[i]-'a']++;
            q.push(i);
        }
    }
    while(!q.empty())
    {

        int po=q.front();q.pop();
        ct++;
        sort(a[po].begin(),a[po].end());
        for(int i=0;i<a[po].size();i++)
        {
            int j=a[po][i];
            w[j]--;
            if(w[j]==0)
                q.push(j);
             if(i>=1){
                if(a[po][i]==a[po][i-1])
                      continue;
            }
            for(int k=0;k<26;k++){
                    if(k==s[j]-'a')
                        dp[j][k]=max(dp[j][k],dp[po][k]+1);
                    else
                        dp[j][k]=max(dp[j][k],dp[po][k]);
            }
            ans=max(ans,dp[j][s[j]-'a']);
        }

    }
    if(ct<n){
        cout<<"-1"<<endl;
        exit(0);
    }
    else
        cout<<ans<<endl;
}
int main()
{

    cin>>n>>m;
    cin>>(s+1);
    memset(w,0,sizeof(w));
    for(int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
            a[x].push_back(y);
            w[y]++;
    }
    son();
}