题目大意:

给定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. poj3292

    Semi-prime H-numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8677   Accepted: 3 ...

  2. 爬虫入门【1】urllib.request库用法简介

    urlopen方法 打开指定的URL urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, ca ...

  3. CoreMotion 加速器陀螺仪

    初始化CoreMotion #import <CoreMotion/CoreMotion.h> CMMotionManager *motionManager = [[CMMotionMan ...

  4. 【python】-- 元组、字典

    元组 元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表 用途:一般情况下用于自己写的程序能存下数据,但是又希望这些数据不会被改变,比如:数据库连接信息等 1.访问元 ...

  5. Struts2学习总结(完整版)

    一.搭建struts2环境 1.jar包的导入 主要是到 解压其中的一个工程,得到里面lib下包含的jar包 把这里的所有的jar包拷贝到项目的 WEB-INF目录下的lib文件夹下面. 2.配置st ...

  6. 添加启动项及常用Windows+R

    常用Windows+R services.msc---本地服务设置 msconfig---系统配置实用程序 mspaint--------画图板 notepad--------打开记事本 Nslook ...

  7. 每天一个Linux命令(34)grep命令

          grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具 ...

  8. golang 获取指定目录下的子文件列表

    GO语言按照深度遍历文件 原创 2016年07月20日 09:45:19 标签: go语言 / 遍历 / string 1971 常规方法不使用pathfilepath包 go的filepath包 g ...

  9. 转的es6 =>函数

    原文地址 箭头函数=>无疑是ES6中最受关注的一个新特性了,通过它可以简写 function 函数表达式,你也可以在各种提及箭头函数的地方看到这样的观点--"=> 就是一个新的 ...

  10. Linux 上关于iptables

    有几个命令: 1.service iptables staus   2.service iptables start    3.service iptables restart   有个配置文件/ec ...