zoukankan      html  css  js  c++  java
  • 【Codeforces Round #460 (Div. 2) D】Substring

    【链接】 我是链接,点我呀:)
    【题意】

    在这里输入题意

    【题解】

    如果有环 ->直接输出-1 (拓扑排序如果存在某个点没有入过队列,说明有环->即入队的节点个数不等于n

    否则。
    说明可以做拓扑排序。
    ->是一个有向无环图。
    那么定义f[x][y]
    表示x节点前面的某条路径中,字母y出现的最多次数是多少次。
    在拓扑排序的时候做DP就好。
    (可以百度:有向无环图 DP 应该有挺多类似的题的

    从入度为0的点开始进行DP。
    然后遇到分叉的时候也没关系
    取两条路中对应字母的较大值就好。
    所以最后f[x][y]中不同字母的最大值可能就是不同的路径了。
    (是哪一条不好说
    然后显然你尽可能地多走一点路总是没错的。
    (走过的点越多,字母出现的频率越高。

    所以肯定是从一个端点到达另外一个端点。
    (即从入度为0的端点开始走.

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cstdio>
    using namespace std;
    
    const int N = 3e5;
    
    int n,m,k,flag[N+10],now,dp[N+10][30];
    char s[N+10];
    vector<int> g[N+10];
    int ru[N+10],a[N+10];
    queue<int> dl;
    
    int main(){
        scanf("%d%d",&n,&m);
        scanf("%s",s+1);
    
        for (int i = 1;i <= m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            ru[y]++;
        }
    
        for (int i = 1;i <= n;i++){
            a[i] = s[i]-'a';
            if (ru[i]==0){
                dp[i][a[i]]++;
            }
        }
    
        int num = 0;
    
        for (int i = 1;i <= n;i++)
            if (ru[i]==0){
                num++;
                dl.push(i);
            }
    
        while (!dl.empty()){
            int x = dl.front();
            dl.pop();
            for (int y:g[x]){
                if (ru[y]<=0) continue;
                for (int i = 0;i < 26; i++){
                    dp[y][i] = max(dp[y][i],dp[x][i] + (a[y]==i) );
                }
                ru[y]--;
                if (ru[y]==0){
                    num++;
                    dl.push(y);
                }
            }
        }
    
        if (num!=n){
            puts("-1");
            return 0;
        }
    
        int ma = 0;
        for (int i = 1;i <= n;i++){
            for (int j = 0;j < 26;j++){
                ma = max(ma,dp[i][j]);
            }
        }
        printf("%d
    ",ma);
      	return 0;
    }
    
  • 相关阅读:
    jquery Banner 图片自动轮换显示
    JavaScript:appendDiv(append和appendChild的区别)
    JavaScript:addEventListener()和removeEventListener()追加事件和删除追加事件
    Cesium源码之CesiumMath(1.62版)
    cesium功能插件
    JavaScript之prototype
    JavaScript规范define(AMD)
    Cesium之时间
    Cesium CallbackProperty实例
    pku3620 Avoid The Lakes 查找最大连通湖(简单深搜)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/8396531.html
Copyright © 2011-2022 走看看