我是靠谱客的博主 俊逸万宝路,最近开发中收集的这篇文章主要介绍CF 919 D. SubstringD. Substring,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

D. Substring

链接

题意:

  在一张有向图中,定义路径的权值为路径中出现次数最多的字符出现的次数,求一条权值最大的路径。如果权值可以无限大,输出-1。

分析:

  注意是一张有向图。如果存在环那么输出-1,否则枚举字符,dp一下。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
inline int read() {
int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}
const int N = 300005;
struct Edge { int to, nxt; } e[N];
int f[N], head[N], deg[N], q[N], d[N], En;
char s[N];
bool vis[N];
void add_edge(int u,int v) {
++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
deg[v] ++;
}
int main() {
int n = read(), m = read();
scanf("%s", s + 1);
for (int i = 1; i <= m; ++i) {
int u = read(), v = read();
add_edge(u, v);
}
int L = 1, R = 0;
for (int i = 1; i <= n; ++i) {
d[i] = deg[i];
if (!deg[i]) q[++R] = i;
}
while (L <= R) {
int u = q[L ++];
vis[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!(--d[v])) q[++R] = v;
}
}
for (int i = 1; i <= n; ++i)
if (!vis[i]) { puts("-1"); return 0; }
int ans = 0;
for (int c = 'a'; c <= 'z'; ++c) {
L = 1, R = 0;
for (int i = 1; i <= n; ++i) {
f[i] = 0;
d[i] = deg[i];
if (!deg[i]) {
q[++R] = i;
if (s[i] == c) f[i] = 1;
}
}
while (L <= R) {
int u = q[L ++];
ans = max(ans, f[u]);
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
f[v] = max(f[v], f[u] + (s[v] == c)); // !!!
if (!(--d[v])) q[++R] = v;
}
}
}
cout << ans;
return 0;
}

 

转载于:https://www.cnblogs.com/mjtcn/p/10343572.html

最后

以上就是俊逸万宝路为你收集整理的CF 919 D. SubstringD. Substring的全部内容,希望文章能够帮你解决CF 919 D. SubstringD. Substring所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部