zoukankan      html  css  js  c++  java
  • 字符串同构最小表示法

    1,o(n)时间内算法

    string getmin(string s)
    {
        int len=s.length();
        s+=s;
    
        int i=0,j=1,k=0,t;
        while(i<len&&j<len&&k<len)
        {
            t=s[(i+k)%len]-s[(j+k)%len];
            if(t==0) k++;
            else
            {
                if(t>0) i+=k+1;
                else j+=k+1;
                if(i==j) j++;
                k=0;
            }
        }
        string res=s.substr(min(i,j),len);
        return res;
    }

    类似应用题

    牛客-团结就是力量

    团结就是力量(tarjan+字符串hash)-牛客

    题意:给定n个字符串,和m对信息构成图,字符串经过变换后完全相等+两个点互相连通,可以一起出站,团结力:一起出站的最大人数

    解:tarjan求最大连通分量,先将字符串预处理为字典序最小,最后离散化求最大值(连块+核对字符)

     

    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    const int mod=142857;
    const int inf=0x3f3f3f3f;
    typedef long long ll;
    typedef pair<int,int> pii;
    
    string getmin(string s)
    {
        int len=s.length();
        s+=s;
    
        int i=0,j=1,k=0,t;
        while(i<len&&j<len&&k<len)
        {
            t=s[(i+k)%len]-s[(j+k)%len];
            if(t==0) k++;
            else
            {
                if(t>0) i+=k+1;
                else j+=k+1;
                if(i==j) j++;
                k=0;
            }
        }
        string res=s.substr(min(i,j),len);
        return res;
    }
    
    //强连通缩点
    int dfn[maxn],low[maxn],tot;
    int Stack[maxn],vis[maxn],idx;
    int cnt;//连通分量的个数
    int belong[maxn];//记录每个节点的强连通编号
    
    vector<int> G[maxn*2];
    string str[maxn];
    int n,m,ans;
    
    void tarjan(int u)
    {
        dfn[u]=low[u]=++tot;
        vis[u]=1;
        Stack[++idx]=u;
        for(auto v:G[u])
        {
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v])
            {
                low[u]=min(low[u],dfn[v]);
            }
        }
        if(dfn[u]==low[u])
        {
            cnt++;
            int k;
            map<string ,int> mp;
            do
            {
                k=Stack[idx--];
                mp[str[k]]++;//对连通分量计数
                vis[k]=0;
            }while(k!=u);
    
            for(auto it:mp)
             ans=max(ans,it.second);
        }
    }
    int main()
    {
        while(cin>>n>>m)
        {
            for(int i=1; i<=n; i++)
             G[i].clear(),dfn[i]=low[i]=vis[i]=0;
            tot=cnt=0;
            idx=ans=0;
            for(int i=1; i<=n; i++)
             {
                 cin>>str[i];
                 str[i]=getmin(str[i]);
                 //cout<<str[i]<<endl;
             }
            for(int i=0; i<m; i++)
             {
               int u,v;
               cin>>u>>v;
              G[u].push_back(v);
             }
            for(int i=1; i<=n; i++)
             {
              if(!dfn[i])
               tarjan(i);
             }
            printf("%d
    ",ans);
        }
        system("pause");
        return 0;
    }

     

     

        
  • 相关阅读:
    changing a pointer rather than erasing memory cells
    验证码识别 edge enhancement 轮廓增强 region finding 区域查找
    Manipulating Data Structures
    passing parameters by value is inefficient when the parameters represent large blocks of data
    Aliasing 走样
    Artificial Intelligence Research Methodologies 人工智能研究方法
    Thread safety
    include pointers as a primitive data type
    flat file
    functional cohesion
  • 原文地址:https://www.cnblogs.com/sweetlittlebaby/p/13332650.html
Copyright © 2011-2022 走看看