题目大意:

给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系。问有多少个串可能成为字典序最小的串,并输出这些串。n <= 30,000 , m <= 300,000

题解:

首先我们可以把所有的串插入到Trie树中。

然后我们枚举每个串,判断是否存在可行方案

我们枚举到一个串,那么我们就在Trie树中进行查找

每一次从某一个节点向下走的时候,我们都要保证当前走的这条支路是字典序最小的

也就是这条支路上的字母的字典序小于这个节点上的其他所有支路的字典序

所以我们就成功的找出了一些字典序的大小关系

所以我们只需要判断这个关系是不是存在环,如果存在环那么一定不可行

否则即可行

判环嘛。。。用拓扑排序不久好了嘛233.

然后让我来吐槽一下这个cin,cout会RE的题目

共30000个字符串,总长300000,是不是我要开一个30000*300000的char数组?

这内存不还得飞起来啊!!!!

用string不久好了? cin cout 不能用!!!你拿什么读入和输出啊!!!!

什么 cin cout 不能用???

可以用 ! 只是RE罢了!!!!

那怎么读入!!!??

你可以先读入一个char数组,然后转成string,然后输出的时候用putchar输出

。。。 。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 30010;
const int maxc = 300010;
int ch[maxc][27],nodecnt;
bool ed[maxc];
inline void insert(string s){
int nw = 0,len = s.size();
for(int i=0;i<len;++i){
if(ch[nw][s[i]-'a'] == 0) ch[nw][s[i]-'a'] = ++nodecnt;
nw = ch[nw][s[i]-'a'];
}ed[nw] = true;
}
bool mp[40][40];int deg[40];
int q[40],l,r;
inline bool judge(string s){
memset(mp,0,sizeof mp);
memset(deg,0,sizeof deg);
int nw = 0,len = s.size();
for(int i=0;i<len;++i){
for(int c='a';c<='z';++c){
if((c == s[i]) || (ch[nw][c - 'a'] == 0)) continue;
if(!mp[s[i]-'a'][c-'a']){
mp[s[i]-'a'][c-'a'] = true;
++deg[c-'a'];
}
}
if(ed[nw]) return false;
nw = ch[nw][s[i]-'a'];
}
l = 0;r = -1;
for(int i=0;i<26;++i){
if(deg[i] == 0) q[++r] = i;
}
while(l <= r){
int u = q[l++];
for(int i=0;i<26;++i){
if(mp[u][i]){
if(--deg[i] == 0) q[++r] = i;
}
}
}
if(r == 25) return true;
return false;
}
bool flag[maxn];
string s[maxn];
char str[maxc];
int main(){
int n;read(n);
for(int i=1;i<=n;++i){
scanf("%s",str);
int m = strlen(str);s[i] = "";
for(int j=0;j<m;++j){
s[i] = s[i] + str[j];
}insert(s[i]);
}int ans = 0;
for(int i=1;i<=n;++i){
if(judge(s[i])){
flag[i] = true;
++ ans;
}
}
printf("%d\n",ans);
for(int i=1;i<=n;++i){
if(flag[i]){
int m = s[i].size();
for(int j=0;j<m;++j){
putchar(s[i][j]);
}puts("");
}
}
getchar();getchar();
return 0;
}

bzoj 3012: [Usaco2012 Dec]First! Trie+拓扑排序的更多相关文章

  1. BZOJ 3012: [Usaco2012 Dec]First! 字典树 + tarjan

    Code: #include<bits/stdc++.h> #define maxn 1000003 using namespace std; char str[maxn],strtot[ ...

  2. 【BZOJ3012】[Usaco2012 Dec]First! Trie树+拓补排序

    [BZOJ3012][Usaco2012 Dec]First! Description Bessie has been playing with strings again. She found th ...

  3. [bzoj3012][luogu3065][USACO12DEC][第一!First!] (trie+拓扑排序判环)

    题目描述 Bessie has been playing with strings again. She found that by changing the order of the alphabe ...

  4. BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )

    子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 -------------------------------------------------------------- ...

  5. BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]

    2938: [Poi2000]病毒 题意:判断是否存在无限长的不含模式串的字符串.只有01. 建出套路DP的转移图,判断有环就行了 练习一下拓扑排序 #include <iostream> ...

  6. E【中】假的字符串(trie+拓扑排序)

    题目 E[中]假的字符串 做法 一个字符串能作为最小值最基础的条件为不能出现前缀字符串 我们需要确定一种每个字符的排名使得\(s\)作为最小值,另有很多字符串\(t\),与\(s\)第一个不相同的位置 ...

  7. bzoj 4010: [HNOI2015]菜肴制作【拓扑排序】

    也就是给定有向图,求最小字典序的拓扑序,直接用小根堆就行(或者反着建图用大根堆) #include<iostream> #include<cstdio> #include< ...

  8. bzoj 3470: Freda’s Walk【拓扑排序+期望dp】

    dfs会T,只好正反两遍拓扑了-- #include<iostream> #include<cstdio> #include<queue> #include< ...

  9. bzoj 1774: [Usaco2009 Dec]Toll 过路费【排序+Floyd】

    非常迷的一道题啊 我觉得挺对的版本只得了30 总之就是Floyd·改,开两个数组,一个是d[i][j]就是普通的只有边权的最短路,a[i][j]是题目要求的那种 具体改的地方是把枚举中转点的地方把中转 ...

随机推荐

  1. Python 字符串拼接、格式化输出、深浅复制

    拼接:"+"号(同类型可拼接) >>>li = [1,2] >>>li + li [1,2,1,2] >>>li*2 [1,2 ...

  2. NSURLSession各文件关系

    NSURLSession   通过session创建任务 @property (class, readonly, strong) NSURLSession *sharedSession; + (NSU ...

  3. 在Ubuntu安装go编译环境

    在Ubuntu安装go编译环境 好记性不如烂笔头,所以趁热打铁记录下golang编译环境的安装过程. 首先下载一些依赖包: sudo apt-get install bison ed gawk gcc ...

  4. SAP文件夹的判断与创建

    [转自 http://blog.csdn.net/saphome/article/details/6956918] SAP文件夹存在的判断与创建 2010-08-29 20:15 相关函数:WS_QU ...

  5. 3.11课·········异常语句与for循环重复

    异常语句try catch finally try//保护执行里面的代码段,若其中一句有错误,直接跳转到catch,不会管下面的内容 { Console.Write("请输入一个整数&quo ...

  6. CodeForces - 580C Kefa and Park 【BFS】

    题目链接 http://codeforces.com/problemset/problem/580/C 题意 根节点是 1 然后所有的叶子结点都是饭店 从根节点到叶子结点的路径上 如果存在 大于m 个 ...

  7. Kattis - names Palindrome Names 【字符串】

    题目链接 https://open.kattis.com/problems/names 题意 给出一个字符串 有两种操作 0.在字符串的最末尾加一个字符 1.更改字符串中的一个字符 求最少的操作步数使 ...

  8. 经典c语言题

    1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 2. 写一个“标 ...

  9. java中如何制作可双击执行的程序--jar打包工具的使用

    假定当前工作目录在E盘: 1.带包编译:javac -d c:\ MyMenuDemo.java 2.DOS命令行切换到c盘,注意,这里一般切换到的是用户文件目录,需要手动切换到C盘根目录 >C ...

  10. Android 双u盘方案【转】

    本文转载自:https://blog.csdn.net/kc58236582/article/details/49618445 1      L1813系统上双U盘设计方案——系统设计 1.1     ...