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.
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 a single line with a single integer denoting the largest value. If the value can be arbitrarily large, output -1 instead.
5 4 abaca 1 2 1 3 3 4 4 5
3
6 6 xzyabc 1 2 3 1 2 3 5 4 4 3 6 4
-1
10 14 xzyzyzyzqx 1 2 2 4 3 5 4 5 2 6 6 8 6 5 2 10 3 9 10 9 4 6 1 10 2 8 3 7
4
In the first sample, the path with largest value is 1 → 3 → 4 → 5. The value is 3 because the letter 'a' appears 3 times.
题意:
有一个字符串,然后可以根据边的情况得到多个子串,求所有子串中每个子串中同一字母出现最多的次数的最大值,若其为无穷大则输出 '-1'
思路:
可以知道输出 '-1' 的情况就是自成环。
要做的就是:
1、判断是否成环 2、求出每个串中每个字母出现的次数
为了避免多次计算更新,所以起始点选为入度为0的点
每个点记录的是以该点为起始点的所有子串中的最大字母出现次数。
如果自成环则可能没有入度为零的点
所以在搜完入度为0的点还需要在判断是否成环
即对所有未访问的点进行dfs
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; const int N = 3e5 + 10; int n,m,a,b,ans[30],cnt[N][30]; int u[N],nt[N],ft[N],sz = 0,flag = 0; int vis[N],use[N],in_deg[N]; char s[N]; void dfs(int pos){//后序遍历 use[pos] = 1; vis[pos] = 1; for(int i=ft[pos];i;i=nt[i]){ int next = u[i]; if(vis[next]){ flag = -1; return;//自成环 } if(!use[next]) dfs(next); for(int j=0;j<26;j++) cnt[pos][j] = max(cnt[pos][j], cnt[next][j]); //大的更新 if(flag) return; } cnt[pos][s[pos]-'a']++; vis[pos] = 0; } int main() { scanf("%d%d%s",&n,&m,s+1); for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); u[++sz] = b; nt[sz] = ft[a]; ft[a] = sz; in_deg[b]++;//入度 } for(int i=1;i<=n;i++){ if(in_deg[i]) continue;//找到入度为0的进行dfs dfs(i);//因为该店为起点,所以该点的字母出现次数即为以该点为起始点的子串中的最大次数 for(int j=0;j<26;j++) ans[j] = max(ans[j], cnt[i][j]); } for(int i=1;i<=n;i++){ if(use[i]) continue; dfs(i);//对剩下的还未访问过的点dfs判断是否自成环 } int Ans = flag;//当自成环时 flag = -1 if(!Ans) for(int i=0;i<26;i++) Ans = max(Ans, ans[i]); printf("%d\n",Ans); return 0; }