Codeforces 919 D Substring

题目描述

You are given a graph with nn nodes and mm 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 33 . Your task is find a path whose value is the largest.

输入输出格式

输入格式:

 

The first line contains two positive integers n,mn,m ( 1<=n,m<=3000001<=n,m<=300000 ), denoting that the graph has nn nodes and mmdirected edges.

The second line contains a string ss with only lowercase English letters. The ii -th character is the letter assigned to the ii -th node.

Then mm lines follow. Each line contains two integers x,yx,y ( 1<=x,y<=n1<=x,y<=n ), describing a directed edge from xx to yy . Note that xx can be equal to yy and there can be multiple edges between xx and yy . 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.

 

输入输出样例

输入样例#1: 
5 4
abaca
1 2
1 3
3 4
4 5
输出样例#1: 
3
输入样例#2: 
6 6
xzyabc
1 2
3 1
2 3
5 4
4 3
6 4
输出样例#2: 
-1
输入样例#3: 
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
输出样例#3: 
4

说明

In the first sample, the path with largest value is 1→3→4→51345 . The value is 33 because the letter 'a' appears 33 times.

 

XJB DP就行了,之前判一下是不是DAG

 

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define ll long long
#define maxn 300005
using namespace std;
int ans=0,g[maxn];
int n,m,id[maxn],u,v;
int f[maxn],hd[maxn];
int to[maxn],ne[maxn];
bool vis[maxn];
char s[maxn];

inline int num(char x){
	return x-'a';
}

inline bool topsort(){
	queue<int> q;
	int x,tot=0;
	
	for(int i=1;i<=n;i++) if(!id[i]) q.push(i);
	
	while(!q.empty()){
		x=q.front(),q.pop(),tot++;
		for(int i=hd[x];i;i=ne[i]) if(!(--id[to[i]]))
		    q.push(to[i]);
	}
	
	return tot==n;
}


int dp(int x){
	if(vis[x]) return g[x];
	vis[x]=1,g[x]=0;
	for(int i=hd[x];i;i=ne[i]) g[x]=max(g[x],dp(to[i]));
	g[x]+=f[x];
	return g[x];
}

int main(){
	scanf("%d%d",&n,&m);
	scanf("%s",s+1);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&u,&v);
		to[i]=v,ne[i]=hd[u];
		hd[u]=i,id[v]++;
	}
	
	if(!topsort()){
		puts("-1");
		return 0;
	}
	
	for(int i=0;i<26;i++){
		memset(vis,0,sizeof(vis));
		for(int j=1;j<=n;j++) f[j]=(num(s[j])==i);
		
		for(int j=1;j<=n;j++) ans=max(ans,dp(j));
	}
	
	printf("%d\n",ans);
	return 0;
	
}

  

转载于:https://www.cnblogs.com/JYYHH/p/8474694.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值