题目大意:

给定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. 自然常数e的神奇之美

  3. Symfony 使用KnpTimeBundle

    使用time_diff时出现:diff.ago.hour; 解决:1:引入"knplabs/knp-time-bundle": "^1.7",https://g ...

  4. TCP标准模板

    伪代码 #创建一个TCP服务器 ss = socket() #创建服务器套接字 ss.bind() #把地址绑定到套接字上 ss.listen() #监听连接 inf_loop: #服务器无线循环 c ...

  5. MySQL 创建索引(Create Index)的方法和语法结构及例子

    MySQL 创建索引(Create Index)的方法和语法结构及例子 MySQL 创建索引(Create Index)的方法和语法结构及例子   CREATE INDEX Syntax CREATE ...

  6. Oracle数据库体系结构(1)整体概述

    oracle数据库的存储结构: 逻辑存储结构:oracle内部的组织和管理数据的方式 物理存储结构:oracle外部(操作系统)组织和管理数据的方式 oracle对逻辑存储结构和物理存储结构的管理是分 ...

  7. <linux报错解决>在Fedora21下安装vmware报错的解决办法

    关于VMWARE WORKSTATION在Fedora21下的安装问题 (1)在Fedora21下安装vmware如果在终端下启动,提示你找不到内核头文件Kernel Headers的话使用命令: s ...

  8. 次小生成树 POJ 2728

    #include <cstdio>#include <cstring>#include <iostream>#include <algorithm>us ...

  9. 剑指offer之 二维数组的查找

    package Problem3; public class Find { /* * 题目描述:二维数组中的查找 * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下的顺序排 ...

  10. MYSQL函数 Cast和convert的用法详解

    MYSQL Cast函数是非常重要的MYSQL函数,下面就将为您详细介绍MYSQL Cast函数的语法及其使用,希望能让您对MYSQL Cast函数有更多的认识. BINARY     BINARY操 ...