• CodeForces


    题意:将一个字符串上的n个字符视作点,给出m条有向边,求图中路径上最长出现的相同字母数。

    分析:首先如果这张图中有环,则可以取无限大的字符数,在求拓扑排序的同时可以确定是否存在环。

    之后在拓扑排序的结果上分别对26个字母dp求出最大结果,并取最大值(一定要分别对每个字母dp,否则会出现问题)。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn =3e5+10;
    int N,M;
    vector<int> G[maxn];
    vector<int> topo;
    int indeg[maxn];
    int dp[maxn][28];
    char str[maxn];
    
    void init()
    {
        topo.clear();
        memset(indeg,0,sizeof(indeg));
        for(int i=0;i<=N;++i)   G[i].clear();
    }
    
    bool circle()
    {
        int v,u,cnt=0;
        queue<int> Q;
        for(int i=1;i<=N;++i){
            if(!indeg[i]){
                Q.push(i);
                cnt++;
            }
        }
        while(!Q.empty()){
            v= Q.front(); Q.pop();
            topo.push_back(v);
            for(int i=0;i<G[v].size();++i){
                u =G[v][i];
                indeg[u]--;
                if(!indeg[u]){ 
                    Q.push(u);
                    cnt++;
                }
            }                
        }
        if(cnt==N) return false;
        else return true;
    }
    
    int solve(int key)
    {
        memset(dp,0,sizeof(dp));
        int res=0;
        int e,v,u;
        for(int i =0;i<topo.size();++i){
            v =topo[i];
            e = str[v]-'a';
            if(e==key)
                dp[v][e]++;
            res = max(res,dp[v][key]);
            for(int j = 0;j<G[v].size();++j){
                u = G[v][j];
                dp[u][key]= max(dp[u][key],dp[v][key]);
            }
        }
        return res;
    }
    
    int main()
    {
        int v,u;
        while(~scanf("%d%d",&N,&M)){
            init();
            scanf("%s",str+1);
            for(int i=0;i<M;++i){
                scanf("%d%d",&v,&u);
                G[v].push_back(u);
                indeg[u]++;        
            }
            if(circle()){
                printf("-1
    ");
                continue;
            }
            int res=0;
            for(int i=0;i<26;++i){
                res=max(res,solve(i));
            }
            printf("%d
    ",res);
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    HashMap源码分析
    静态代理和装饰模式的区别
    自动内存管理
    ReentrantReadWriteLock
    ReentranLock
    对象的内存布局
    对象的创建
    [P2495][SDOI2011]消耗战——虚树
    [HDU2966]In case of failure——KD树
    [Gym-101158J]Coverthe Polygon with Your Disk——梯度下降,模拟退火
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9466607.html
Copyright © 2020-2023  润新知