这场cf真的是被C题气疯了,最后一个小时都是在蹲点hack C题,赛后队友说D题巨简单,结束后看了下题意,确实是很简单,感觉亏疯了啊(虽然场上也不一定能A,手动滑稽)
题意很简单就是求有向图的权值最大的那条路的权值,权值等于路上出现次数最多的字符的出现次数。
数据为3e5,题目中已知字符只有a-z的lowercase English letter,那么说明只有26个字符需要去判断,26*3e5讲道理是不会爆1000ms的,况且这题给你3000ms(实际上照这样写我跑了1481ms,比自己估算的结果大了一点,不过还是A了),那么直接暴力dfs出每个字符的最长出现次数,存到Max里再更新25遍Max便得到了答案。
自己A了之后看了下队友的代码,plw判断环路的时候直接套了scc模板,然后跑了300ms不到,emmmmm,scc反正我是不会,寒假剩下几天可以学一下。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<limits.h>
#include<string.h>
#include<map>
#include<list>
using namespace std;
typedef long long ll;
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define eps double(1e-6)
#define pi acos(-1.0)
#define lson root << 1
#define rson root << 1 | 1
int n,m;
int flag=1;
int cnt[300005];
int vis[300005];
char s[300005];
vector<int> a[300005];
int dfs(int i,char ss)
{
if(vis[i]==1)
{
flag=0;
return 0;
}
if(vis[i]==-1)
return cnt[i];
if(s[i]==ss)
cnt[i]++;
vis[i]=1;
int Max=0;
for(auto k: a[i])
{
int shu=dfs(k,ss);
//cout<<shu<<endl;
Max=max(Max,shu);
}
//cout<<Max<<endl;
cnt[i]+=Max;
vis[i]=-1;
return cnt[i];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
cin>>s + 1;
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
if(x==y)
flag=0;
a[x].push_back(y);
}
int sum=-1;
for(int i=0;i<26;i++)
{
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
char ch=i+'a';
//cout<<ch<<endl;
for(int j=1;j<=n;j++)
{
if(!vis[j])
dfs(j,ch);
}
int da=*max_element(cnt+1,cnt+n+1);
//cout<<da<<endl;
sum=max(sum,da);
}
if(flag)
cout<<sum<<endl;
else
cout<<-1<<endl;
}