题目地址:
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(); }
浙公网安备 33010602011771号