zoukankan      html  css  js  c++  java
  • Codeforces 919D:Substring(拓扑排序+DP)

    D. Substring

    time limit: per test3 seconds
    memory limit: per test256 megabytes
    inputstandard: input
    outputstandard: output

    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.

    Input

    The first line contains two positive integers n,m(1n,m300000)n,m (1≤n,m≤300000), denoting that the graph has nn nodes and mm directed 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 m lines follow. Each line contains two integers x,y(1x,yn)x,y (1≤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

    Output a single line with a single integer denoting the largest value. If the value can be arbitrarily large, output 1-1 instead.

    Examples

    input

    5 4
    abaca
    1 2
    1 3
    3 4
    4 5
    

    output

    3
    

    input

    6 6
    xzyabc
    1 2
    3 1
    2 3
    5 4
    4 3
    6 4
    

    output

    -1
    

    input

    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
    

    output

    4
    

    Note

    In the first sample, the path with largest value is 13451→3→4→5. The value is 33 because the letter ‘a’ appears 33 times.

    题意

    给出有nn个点和mm条边的有向图,每个节点上有一个小写字母,求所有通路中出现次数最多的字母出现的次数,如果出现了无数次,输出1-1

    Solve

    用拓扑排序判断图中是否有环,如果有环,那么环上的字母出现的次数为无限多次,输出1-1
    如果能够进行拓扑排序,对于每次遍历的节点,更新当前路上字母出现次数的最大值
    dp[i][j]dp[i][j]表示到达节点ii,字母a+j'a'+j出现的最大次数

    Code

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define ms(a,b) memset(a,b,sizeof(a))
    #define INF 0x7f7f7f7f
    const int maxn=1e6+10;
    const int mod=1e9+7;
    using namespace std;
    int n,m;
    char ch[maxn];
    int visi[maxn];
    // dp[i][j]表示到i位置,字母j出现的最多次数
    int dp[maxn][50];
    int cnt;
    vector<int>v[maxn];
    queue<int>que;
    void topo()
    {
    	for(int i=1;i<=n;i++)
    		if(!visi[i])
    		{
    			que.push(i);
    			dp[i][ch[i]-'a']++;
    		}
    	while(!que.empty())
    	{
    		cnt++;
    		int res=que.front();
    		que.pop();
    		int sz=v[res].size();
    		for(int i=0;i<sz;i++)
    		{
    			visi[v[res][i]]--;
    			if(!visi[v[res][i]])
    				que.push(v[res][i]);
    			for(int j=0;j<26;j++)
    				dp[v[res][i]][j]=max(dp[v[res][i]][j],dp[res][j]+(ch[v[res][i]]-'a'==j));
    		}
    	}
    	if(cnt<n)
    		cout<<-1<<endl;
    	else
    	{
    		int ans=0;
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=0;j<26;j++)
    				ans=max(ans,dp[i][j]);
    		}
    		cout<<ans<<endl;
    	}
    }
    int main(int argc, char const *argv[])
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cin>>n>>m;
    	cin>>(ch+1);
    	ms(visi,0);
    	int x,y;
    	for(int i=0;i<m;i++)
    	{
    		cin>>x>>y;
    		v[x].push_back(y);
    		visi[y]++;
    	}
    	topo();
    	return 0;
    }
    
  • 相关阅读:
    我认为的架构师
    Jenkins github账号密码验证方式失效 解决方式
    android逆向奇技淫巧二十一:ida反反调试&加密算法跟踪(未完待续)(六)
    android逆向奇技淫巧十九:unidbg模拟执行和trace x音so代码(四)
    android逆向奇技淫巧十八:x音so层代码花指令防护分析(三)
    android逆向奇技淫巧十七:android客户端自动x红包(一):代码原理分析
    测试工具安装汇总
    javascript事件节流和防抖
    CompletableFuture-更优雅的使用多线程
    青春
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11054967.html
Copyright © 2011-2022 走看看