zoukankan      html  css  js  c++  java
  • CodeForces-919D Substring DP,拓扑排序

    给定一个有 n 个节点和 m 条有向边的图。每个节点上有一个小写字母。

    我们将路径的值定义为最经常出现的字母的数目。例如,如果路径上的字母是 “abaca”,那么该路径的值是 3

    你的任务是找到一条值最大的路径,并将这条路径的值输出。

    显然条件是必须在一条路径上,容易想到限制要求拓扑排序,因此可以在拓扑序上DP

    dp[i][j]表示前i个点中,字母j出现的次数。

    int n, m, u, v;
    int num;
    queue<int> q;
    int dp[300005][27];
    int Indeg[300005];
    char s[300005];
    vector<int> vec[300005];
    
    bool topo() {
        while (!q.empty()) q.pop();
        num = 0;
        for (int i = 1; i <= n; i++) if (!Indeg[i]) {
            q.push(i);
            dp[i][s[i] - 'a']++;
        }
        while (!q.empty()) {
            int now = q.front();
            q.pop();
            num++;
            for (int i = 0; i < vec[now].size(); i++) {
                if (--Indeg[vec[now][i]] == 0) {
                    q.push(vec[now][i]);
                }
                for (int j = 0; j < 26; j++) {
                    dp[vec[now][i]][j] = max(dp[vec[now][i]][j], dp[now][j] + (s[vec[now][i]] - 'a' == j));
                }
            }
        }
        if (n == num) return true;
        else return false;
    }
    
    int main() {
        n = readint();
        m = readint();
        scanf("%s", s + 1);
        for (int i = 0; i < m; i++) {
            int x = readint();
            int y = readint();
            vec[x].push_back(y);
            Indeg[y]++;
        }
        if (!topo()) puts("-1");
        else {
            int Max = -1;
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j < 26; j++) {
                    Max = max(Max, dp[i][j]);
                }
            }
            Put(Max);
        }
    }
  • 相关阅读:
    Java并发编程:ThreadLocal
    线程的3种实现方式
    线程的生命周期
    并行与并发
    wordcount详解shuffle机制(转)
    linux vi编译卡死原因
    django2.0集成xadmin0.6报错集锦
    drf框架
    Django中 media资源配置
    Django-rest framework框架的安装配置和简介、Restful接口规范、基于原生django书写满足restful规范的接口
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13526209.html
Copyright © 2011-2022 走看看