D. Substring
time limit per test
3 seconds
You are given a graph with n nodes and m directed edges. One lowercase letter is assigned to each node. We define a path's value as the number of the most frequently occurring letter. For example, if letters on a path are "abaca", then the value of that path is 3. Your task is find a path whose value is the largest.
Input
The first line contains two positive integers n, m (1 ≤ n, m ≤ 300 000), denoting that the graph has n nodes and m directed edges.
The second line contains a string s with only lowercase English letters. The i-th character is the letter assigned to the i-th node.
Then m lines follow. Each line contains two integers x, y (1 ≤ x, y ≤ n), describing a directed edge from x to y. Note that x can be equal to y and there can be multiple edges between x and y. Also the graph can be not connected.
Output
Output a single line with a single integer denoting the largest value. If the value can be arbitrarily large, output -1 instead.
题意
题解
从一个入度不为0的点跑的话,不如从他的父节点开始跑,长度更长,以此类推,得到从入度为0的点开始跑。而且该图为有向图,有自环和平行边,用拓扑排序也好判断,所以用拓扑排序。设a[N][26],第一维是编号,第二维是当前字符出现的最大频率。用父节点的值更新当前节点的值。
代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef double db; typedef pair<int,int> pii; typedef vector<int> vi; #define check system("pause") #define all(x) (x).begin(),(x).end() #define de(a) cout<<#a<<" = "<<a<<endl #define dd(a) cout<<#a<<" = "<<a<<" " #define mp make_pair #define pb push_back #define fi first #define se second #define lowbit(a) ((a)&-(a)) #define INF 0x3f3f3f3f const ll mod = 1e9+7; const int N = 3e5+20; #define dep(i,a,b) for(int i=(a);i>=(b);i--) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define mes(p,b) memset(p,b,sizeof(p)) #define sz(x) int(x.size()) int a[N][26],n,m,s[N],in[N];vi to[N]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n>>m; rep(i,1,n){ char c; cin>>c; s[i]=c-'a'; } rep(i,1,m){ int x,y; cin>>x>>y; to[x].pb(y); in[y]++; } queue<int> q; rep(i,1,n) if(in[i]==0) q.push(i); int cnt=0,ans=0; while(!q.empty()){ cnt++; int t=q.front();q.pop(); a[t][s[t]]++; ans=max(a[t][s[t]],ans); for(auto i:to[t]){ rep(j,0,25){ a[i][j]=max(a[i][j],a[t][j]); ans=max(ans,a[i][j]); } if(--in[i]==0) q.push(i); } } if(cnt!=n) cout<<-1; else cout<<ans; return 0; }