题意 : 给出含有 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. 【Qt开发】QScrollArea添加布局后没有出现滚动条的解决方法

    [Qt开发]QScrollArea添加布局后没有出现滚动条的解决方法 标签:[Qt开发] 说明:尝试利用滚动区域显示多张图片,为了能够动态地往滚动区域贴图,为滚动区域设置了布局,然后通过布局来添加wi ...

  2. 【VS开发】在VS2010中开发ActiveX控件设置测试容器的方式

    在VS2010中开发ActiveX控件设置测试容器的方式 借鉴文章http://blog.csdn.net/waxgourd0/article/details/7374669 在VS2010中开发MF ...

  3. 使用ocelot作为api网关

    新建网站项目然后添加ocelot 的nuget包 新建ocelot.json的网关的配置文件 { "GlobalConfiguration": { "BaseUrl&qu ...

  4. python 并发编程 多路复用IO模型

    多路复用IO(IO multiplexing) 这种IO方式为事件驱动IO(event driven IO). 我们都知道,select/epoll的好处就在于单个进程process就可以同时处理多个 ...

  5. CentOS7之SVN服务配置

    操作系统:CentOS Linux release 7.2.1511 (Core)    Subversion软件版本:subversion-1.7.14-10.el7.x86_64 1.首先检查sv ...

  6. wode.

    http://www.cnblogs.com/wilber2013/p/4638967.html

  7. Python基础数据类型int

    整型int 赋值运算符 a=1 a+=1 #a=a+1 a-=1 #a=a-1 a*=1 #a=a*1 a/=1 #a=a/1 a**=1 #a=a**1 a%=1 #a=a%1 算数运算符 + - ...

  8. Java Calendar使用

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  9. PHP post调接口代码

    PHP post调接口代码 /** * $url:接口地址 * $data:数组参数 **/ function postData($url, $data) { $ch = curl_init (); ...

  10. StanfordNLP for JAVA demo

    最近工作需要,研究学习 NLP ,但是 苦于官方文档太过纷繁,容易找不到重点,于是打算自己写一份学习线路 NLP 路线图 好博客韩小阳 斯坦福NLP公开课 统计学习方法 好博客 链接地址:https: ...