CodeForces - 919D Substring (拓扑排序+dp)
2024-09-26 10:10:57
题意:将一个字符串上的n个字符视作点,给出m条有向边,求图中路径上最长出现的相同字母数。
分析:首先如果这张图中有环,则可以取无限大的字符数,在求拓扑排序的同时可以确定是否存在环。
之后在拓扑排序的结果上分别对26个字母dp求出最大结果,并取最大值(一定要分别对每个字母dp,否则会出现问题)。
#include<bits/stdc++.h>
using namespace std;
const int maxn =3e5+;
int N,M;
vector<int> G[maxn];
vector<int> topo;
int indeg[maxn];
int dp[maxn][];
char str[maxn]; void init()
{
topo.clear();
memset(indeg,,sizeof(indeg));
for(int i=;i<=N;++i) G[i].clear();
} bool circle()
{
int v,u,cnt=;
queue<int> Q;
for(int i=;i<=N;++i){
if(!indeg[i]){
Q.push(i);
cnt++;
}
}
while(!Q.empty()){
v= Q.front(); Q.pop();
topo.push_back(v);
for(int i=;i<G[v].size();++i){
u =G[v][i];
indeg[u]--;
if(!indeg[u]){
Q.push(u);
cnt++;
}
}
}
if(cnt==N) return false;
else return true;
} int solve(int key)
{
memset(dp,,sizeof(dp));
int res=;
int e,v,u;
for(int i =;i<topo.size();++i){
v =topo[i];
e = str[v]-'a';
if(e==key)
dp[v][e]++;
res = max(res,dp[v][key]);
for(int j = ;j<G[v].size();++j){
u = G[v][j];
dp[u][key]= max(dp[u][key],dp[v][key]);
}
}
return res;
} int main()
{
int v,u;
while(~scanf("%d%d",&N,&M)){
init();
scanf("%s",str+);
for(int i=;i<M;++i){
scanf("%d%d",&v,&u);
G[v].push_back(u);
indeg[u]++;
}
if(circle()){
printf("-1\n");
continue;
}
int res=;
for(int i=;i<;++i){
res=max(res,solve(i));
}
printf("%d\n",res);
}
return ;
}
最新文章
- centos tar压缩与解压缩命令大全
- 完美解决 Linux 下 Sublime Text 中文输入
- Myeclipse 加载ojdbc14.jar步骤
- iOS应用架构谈(二):View层的组织和调用方案(中)
- atexit函数和两种特殊文件权限位
- 【转】并发编程之GCD
- python脚本工具-1 制作爬虫下载网页图片
- JavaScript- The Good Parts Chapter 5 Inheritance
- 白帽子讲Web安全1.pdf
- hdu 1317 XYZZY【Bellheman_ford 判断正环小应用】
- C语言刷新缓冲区(转载)
- python 标准模块shlex
- 学会C sharp计算机编程语言 轻松开发财务、统计软件
- linux系统性能监控--I/O利用率
- ASP.NET Web API之消息拦截
- Oracle&;SQLServer中实现跨库查询
- Ex 6_9 某个字符串处理语言提供了一个将字符串一分为二的基本操作..._第六次作业
- 第七章 :分布式监控与SNMP监控
- Android - 序列化与反序列化
- 五、概念数据模型(CDM生成LDM,PDM和OOM)