题意 : 给出含有 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. 微信小程序开发(一)----- 基础知识

    1.什么是微信小程序 概念:小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用,体现了“用完即走”的理念,用户不需要关心是否安装太多应用的问题, ...

  2. MySQL出现 Access denied for user 'root'@'localhost' (using password:YES) 解决办法

    1.先停止MySQL服务,然后在MySQL安装目录(我的是C:\Program Files (x86)\MySQL\MySQL Server 5.1)找到my.ini文件,在最后一行添加skip-gr ...

  3. 史上最详细 Linux 用户与用户组知识

    1.用户和用户组文件 在 linux 中,用户帐号,用户密码,用户组信息和用户组密码均是存放在不同的配置文件中的. 在 linux 系统中,所创建的用户帐号和其相关信息 (密码除外) 均是存放在 / ...

  4. 分库分表之后全局id咋生成?

    1.面试题 分库分表之后,id主键如何处理? 2.面试官心里分析 其实这是分库分表之后你必然要面对的一个问题,就是id咋生成?因为要是分成多个表之后,每个表都是从1开始累加,那肯定不对啊,需要一个全局 ...

  5. 【6.12校内test】T2 子集

    这道题大概是这三道题里最简单的啦 但这阻止不了我废的脚步 [问题描述] 对于 n=4 时,对应的集合 s={4,3,2,1},他的非空子集有 15 个依次如下: {1} {2} {1,2} {3} { ...

  6. html之input

    <input>在w3c中解释的是用于搜集用户的信息 它其实就是一个输入框,根据type的不同这个框可以用作不同的功能可以输入一个文本,可以定义一个按钮什么的. 属性type一些值的介绍 1 ...

  7. js实现回车键搜索

    前端关键代码: <input type="text" onkeydown="entersearch()" class="form-control ...

  8. Jpa/Hibernate 字节码增强:字段延迟加载

    JPA提供了@Basic注解,实现延迟加载字段的功能,如下: @Basic(fetch = FetchType.LAZY) @Column(name = "REMARK_CONTENT&qu ...

  9. mycat 笔记

    Mycat读写分离.主从切换.分库分表的操作记录   系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库 ...

  10. jquery判断 input type="file"上传文件是否为空

    要想获取type="file"的input内容,用var file = $("id").val();肯定是不行的,下面是代码: html上传按钮为: <i ...