【Codeforces Round #460 (Div. 2) D】Substring

点点圈 提交于 2019-12-19 01:54:43

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


在这里输入题意

【题解】


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

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

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

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

【代码】

#include <bits/stdc++.h>
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(){
    #ifdef LOCAL_DEFINE
        freopen("rush_in.txt", "r", stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);
    cin >> n >> m;
    cin >>(s+1);

    for (int i = 1;i <= m;i++){
        int x,y;
        cin >> x >> y;
        g[x].push_back(y);
        ru[y]++;
    }

    for (int i = 1;i <= n;i++){
        a[i] = s[i]-'a'+1;
        if (ru[i]==0){

            dp[i][a[i]]++;
            dp[i][0] = 1;
        }
    }

    int num = 0;

    for (int i = 1;i <= n;i++)
        if (ru[i]==0){
            num++;
            dl.push(i);
            ru[i] = -1;
        }

    while (!dl.empty()){
        int x = dl.front();
        dl.pop();
        for (int y:g[x]){
            if (ru[y]<=0) continue;
            if (dp[y][0]==0){
                for (int i = 1;i <= 26;i++)
                    dp[y][i] = dp[x][i]+(a[y]==i);
            }else{
                    for (int i = 1;i <=26;i++)
                        dp[y][i] = max(dp[y][i],dp[x][i]+(a[y]==i));
            }
            dp[y][0] = 1;
            ru[y]--;
            if (ru[y]==0){
                num++;
                dl.push(y);
            }
        }
    }
    if (num!=n){
        cout<<-1<<endl;
        return 0;
    }
    int ma = 0;
    for (int i = 1;i <= n;i++)
        if (dp[i][0]){
            for (int j = 1;j <= 26;j++)
                ma = max(ma,dp[i][j]);
        }
    cout<<ma<<endl;
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!