题意 : 给出含有 N 个点 M 条边的图(可能不连通或者包含环),每个点都标有一个小写字母编号,然后问你有没有一条路径使得路径上重复字母个数最多的次数是多少次,例如图上有条路径的顶点标号顺序是  abcaca 那么答案就是 3 ,因为 a 出现了三次,如果答案无穷大则输出 -1

分析 : 

不难联想到是一个动态规划类型的题目

定义 DP[i][j] 为到达顶点 i 时字母 j 最多出现了多少次

显然如果图中有环的话就输出 -1

这也就是说如果图中不存在合法拓扑排序就说明有环

如果存在拓扑排序,那么就是一个DAG

我们可以构造出拓扑序列,然后在这个图上进行上述DP过程

状态转移方程为 dp[ i 出度顶点 ][j] = max{ dp[ i 出度顶点][j], dp[i][j] + (i 出度顶点编号 == j ? 1 : 0) }

可以使用队列构造拓扑排序,在构造的过程中完成 DP

#include<bits/stdc++.h>
using namespace std;
;
struct EDGE{ int v, nxt; }Edge[maxn];
char ch[maxn];
int Deg[maxn];
];
int Head[maxn], cnt;
int N, M;

inline void init()
{
    ; i<=N; i++){
        Head[i] = -, Deg[i] = ;
        ; j<; j++)
            dp[i][j] = ;
    }
    cnt = ;
}

inline void AddEdge(int From, int To)
{
    Edge[cnt].v = To;
    Edge[cnt].nxt = Head[From];
    Head[From] = cnt++;
}

#define Debug 0
int main(void)
{
#if Debug
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // Debug
    while(~scanf("%d %d", &N, &M)){
        ; i<=N; i++)
            scanf(" %c", &ch[i]);
//        for(int i=1; i<=N; i++)
//            putchar(ch[i]);
        init();
        int From, To;
        while(M--){
            scanf("%d %d", &From, &To);
            AddEdge(From, To);
            Deg[To]++;
        }

        queue<int> que;
        while(!que.empty()) que.pop();
        ; i<=N; i++)
            if(!Deg[i]){
                que.push(i);
                dp[i][ch[i]-;
            }

        ;
        while(!que.empty()){
            int v = que.front();
            que.pop();
            num++;
            ; i=Edge[i].nxt){
                int Eiv = Edge[i].v;
                ; j<; j++)
                    dp[Eiv][j] = max(dp[Eiv][j], dp[v][j] + (ch[Eiv]-'a' == j));
                Deg[Eiv]--;
                if(!Deg[Eiv])
                    que.push(Eiv);
            }
        }
        //printf("%d\n", num);
        if(num != N){
            puts("-1");
            continue;
        }else{
            ;
            ; i<=N; i++){
                ; j<; j++){
                    ans = max(ans, dp[i][j]);
                }
            }
            printf("%d\n", ans);
        }
    }
    ;
}

Codeforces 919D Substring ( 拓扑排序 && DAG上的DP )的更多相关文章

  1. CodeForces - 919D Substring (拓扑排序+dp)

    题意:将一个字符串上的n个字符视作点,给出m条有向边,求图中路径上最长出现的相同字母数. 分析:首先如果这张图中有环,则可以取无限大的字符数,在求拓扑排序的同时可以确定是否存在环. 之后在拓扑排序的结 ...

  2. Codeforces 919D Substring (拓扑排序+树形dp)

    题目:Substring 题意:给你一个有向图, 一共有n个节点 , m条变, 一条路上的价值为这个路上出现过的某个字符最多出现次数, 现求这个最大价值, 如果价值可以无限大就输出-1. 题解:当这个 ...

  3. UVA - 10131Is Bigger Smarter?(DAG上的DP)

    题目:UVA - 10131Is Bigger Smarter? (DAG) 题目大意:给出一群大象的体重和IQ.要求挑选最多的大象,组成一个序列.严格的体重递增,IQ递减的序列.输出最多的大象数目和 ...

  4. Codeforces 919D Substring 【拓扑排序】+【DP】

    <题目链接> 题目大意:有一个具有n个节点,m条边的有向图,每个点对应一个小写字母,现在给出每个顶点对应的字母以及有向边的连接情况,求经过的某一条路上相同字母出现的最多次数.如果次数无限大 ...

  5. Codeforces 919D - Substring

    919D - Substring 思路: 拓扑排序判环+DAG上dp+记忆化搜索 状态:dp[i][j]表示以i为起点的路径中j的最大出现次数 初始状态:dp[i][j]=1(i have no so ...

  6. CodeForces 721C Journey(拓扑排序+DP)

    <题目链接> 题目大意:一个DAG图有n个点,m条边,走过每条边都会花费一定的时间,问你在不超过T时间的条件下,从1到n点最多能够经过几个节点. 解题分析:对这个有向图,我们进行拓扑排序, ...

  7. Codeforces 510C (拓扑排序)

    原题:http://codeforces.com/problemset/problem/510/C C. Fox And Names time limit per test:2 seconds mem ...

  8. E - E CodeForces - 1100E(拓扑排序 + 二分)

    E - E CodeForces - 1100E 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方 ...

  9. CodeForces - 1100E 二分+拓扑排序

    题意: 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方案,以及该方案翻转的最大的边权. Inpu ...

随机推荐

  1. idea工具

    1. 使用IntelliJ IDEA 配置JDK(入门)   https://blog.csdn.net/nobb111/article/details/77116259 2. idea 调试快捷键  ...

  2. Spring Security框架进阶、自定义登录

      1.Spring Security框架进阶 1.1 Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安 ...

  3. springBoot2.0使用@slf4j注解记录日志

    1. idea上安装Lombok插件 File --> setting --> Plugins 安装完后重启idea 2. 在springboot项目中修改pom.xml,添加如下配置引入 ...

  4. sqlalchemy query函数可用参数有哪些?

    一.模型名 二.模型对象属性 三.聚合函数 下面就分别为大家讲讲query函数这三种参数的用法. 在讲之前,我已经把数据库连接配置.模型,以及添加数据写好了,代码如下: from sqlalchemy ...

  5. ArcGIS 在VS2010中 ESRI.ArcGIS.SOESupport.dll 无法正常加载的处理

    转自  http://blog.csdn.net/tnt123688/article/details/23186973 问题描述: 打开ArcGIS的SOE模板后,提示  错误 命名空间“ESRI.A ...

  6. RS chap1:好的推荐系统

    一.什么是推荐系统 1.个性化推荐系统:从庞大的电影库中找几部符合你兴趣的电影供你选择. 2.推荐系统是帮助用户快速发现有用信息的工具.和搜索引擎不同的是,推荐系统不需要用户提供明确的需求,而是通过分 ...

  7. laravel5.8 源码分析(1) Route

    https://learnku.com/docs/laravel/5.8 源码路径 vendor\laravel\framework\src\Illuminate\Routing\Router.php ...

  8. keepalived和lvs实现mysql读负载均衡

    keepalived+lvs实现对mysql读负载均衡 环境:redhat 6.5 real server: 172.25.254.189 172.25.254.224 lvs: 172.25.254 ...

  9. hadoop的三大组件安装

    安装过程分3步走: 1.安装namenode主机一台; 2.安装datanode主机三台; 3.启用集群的三大组件: HDFS,Mapreduce,Yarn. 重要的事情: 新建的虚拟机,预备安装ha ...

  10. final修饰符—不可变

    final 修饰符 修饰类 不可以有子类 修饰变量 变量一旦获得初始值就不可改变,不能被重新赋值 成员变量:初始值必须有程序员显式设置,系统不会对其隐式初始化 类变量:静态初始化块 | 声明该类变量时 ...