• 牛客15049 假的字符串(字典树+拓扑排序)


    题意:

    给定n个字符串,互不相等,你可以任意指定字符之间的大小关系(即重定义字典序),求有多少个串可能成为字典序最小的串,并输出它们。

    题解:

    首先,当另一个字符串是当前字符串的前缀时,这个字符串一定不可能是最小的,这一点可以用字典树实现。

    然后,可能出现矛盾的情况,使得当前字符串不可能是最小,这里先在字典树上扫描一遍字符串,将每个节点和它的兄弟萌连一条单向边,这样可以形成一个有向图,对这个有向图做拓扑排序,如果有环,就不合法,否则合法。

    用拓扑排序判环的方法就是查看入队过的节点数是否等于整个有向图的节点数。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e5+10;
    typedef long long ll;
    vector<string> ans;
    string s[maxn];
    int Trie[maxn][27];
    int cnt[maxn];
    int inDegree[27];
    int tot=0,n;
    vector<int> g[27];
    void insert (string s) {
        int root=0;
        for (int i=0;i<s.length();i++) {
            int tt=s[i]-'a';
            if (!Trie[root][tt]) Trie[root][tt]=++tot;
            root=Trie[root][tt];
        }
        cnt[root]++;
    }
    queue<int> q;
    bool topo () {
        ll f=0;
        for (int i=0;i<26;i++) if (!inDegree[i]) q.push(i),f|=(1<<i);
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            for (int i=0;i<g[u].size();i++) {
                int v=g[u][i];
                if (--inDegree[v]==0) q.push(v),f|=(1<<v);
            }
        }
        return f==((1<<26)-1);
    }
    bool check (string s) {
        memset(inDegree,0,sizeof(inDegree));
        int root=0;
        for (int i=0;i<26;i++) g[i].clear();
        for (int i=0;i<s.length();i++) {
            for (int j=0;j<26;j++) {
                int tt=s[i]-'a';
                if (Trie[root][j]&&j!=tt) 
                    inDegree[j]++,g[tt].push_back(j);
            } 
            if (cnt[root]) return false;
            root=Trie[root][s[i]-'a'];
        }
        return topo();
    }
    int main () {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) {
            cin>>s[i];insert(s[i]);
        }
        for (int i=1;i<=n;i++) if (check(s[i])) ans.push_back(s[i]);
        printf("%d
    ",ans.size());
        for (int i=0;i<ans.size();i++) cout<<ans[i]<<'
    ';
        return 0;
    }
  • 相关阅读:
    Matlab之rand(), randn(), randi()函数的使用方法
    matlab给图片插入说明文字
    matlab之find()函数
    excel根据数据源变化的动态图表
    高斯坐标
    (转)Mysql技术内幕InnoDB存储引擎-表&索引算法和锁
    (转)MySQL 插入数据时,中文乱码问题的解决
    (转)防止人为误操作MySQL数据库技巧一例
    (转)mysql explain详解
    (转)一个MySQL 5.7 分区表性能下降的案例分析
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13215838.html
Copyright © 2020-2023  润新知