(我恨字符串)

惯例化简题目:给定n个字符串,可以改变字符的相对大小(在字典序中的大小),问:字符串i是否能成为最小的字符串(字典序)

解题过程:

  • 首先你可以预处理出来26的全排列然后暴力然后你只要用神威太湖之光开O2就能过了
  • 秒切字典树
  • 推出一堆没用的结论。

说一下思考过程:首先字典树能找前缀都知道吧

  1. 观察样例,得:对于不能变成第一的,那么一定是有一个跟它有相同前缀的字符串,但是不完全相等,要有比当前串小的。
  2. 然后和旁边大佬一起歪歪瞎搞:建立一棵字典树,然后对于每个字符串跑一遍字典树,如果能找到相同的前缀&&最终终点不在一个分叉上&&分叉比当前串终点小(这里可能要意会一下....算了我上图)

(打标记的是字串结束的地方,软件为了防止重复在相同的字母后加了数字去重,无用)

先看omm,按照上面的结论,很明显可以,其实不然

然后发现....样例打了从样例发现的结论的脸......

solution:

想想怎么判断无解....

一个条件先于另外一个条件....

如果先到自己头上,那就暴毙了。。。

这....拓扑排序??

貌似是这样。

于是,我们在字典树上跑一下,对于一个分支(相同前缀的几个字符)像这样:

连单向边之后,跑tpsort,如果有环的话(先到自己头上了,不明白自己去学tpsort),那就是一个无解情况

注意,连边不是在树上,而是在字母表上,字母表的每一个都会有初始边(a->b->c->d->e->f->g......->y->z)然后在上述过程中人为加边,然后跑tpsort,一开始我在这里卡住了

然后每个跑就行了,代码没有太大难度,字典树的板子背掉就行了(或者拿临接表硬模)。

代码:(注意,每跑一个要清零。)

#include<bits/stdc++.h>
#define register
using namespace std;
const int maxn=3e5+;
string s[maxn];
struct edge
{
int to,next;
}e[]; int head[],cnt; inline void addedge(int from,int to)
{
e[++cnt].next=head[from];
e[cnt].to=to;
head[from]=cnt;
} int t[maxn][];
int vis[maxn];
int used[][];
int f;
int tot;
int ru[];
int n;
int ans[maxn];
int anscnt;
inline void update(string x)
{
int u=,tt;
for( int i=;i<x.size();i++)
{
tt=x[i]-'a';
if(!t[u][tt])
{
t[u][tt]=++tot;
}
u=t[u][tt];
}
vis[u]=;
}
inline void solve(string x)
{
int u=,tt;
for( int i=;i<x.size();i++)
{
tt=x[i]-'a';
if(vis[u])
{
f=;
return;
}
for( int j=;j<;j++)
{
if(t[u][j]&&j!=tt&&!used[tt][j])
{
used[tt][j]=;
addedge(tt,j);
ru[j]++;
}
}
u=t[u][tt];
}
} inline int tpsort()
{
deque < int > q;
for( int i=;i<;i++)
{
if(ru[i]==)
q.push_back(i);
}
while(!q.empty())
{
int u=q.front();
q.pop_front();
for( int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
ru[v]--;
if(ru[v]==)
{
q.push_back(v);
}
}
}
for( int i=;i<;i++)
{
if(ru[i]!=)
return ;
}
return ;
} int main()
{
ios::sync_with_stdio(false);
cin>>n;
for( int i=;i<=n;i++)
{
cin>>s[i];
update(s[i]);
}
for( int i=;i<=n;i++)
{
cnt=;
f=;
memset(head,,sizeof(head));
memset(ru,,sizeof(ru));
memset(used,,sizeof(used));
solve(s[i]);
if(f) continue;
if(tpsort()) ans[++anscnt]=i;
}
printf("%d\n",anscnt);
for(int i=;i<=anscnt;i++)
{
printf("%s\n",s[ans[i]].c_str());
}
return ;
}

(完)

「Usaco2012 Dec」第一(字典树+拓扑排序)的更多相关文章

  1. Luogu P3065 [USACO12DEC]第一!First!【字典树/拓扑排序】By cellur925

    题意:给你许多字符串,你可以改变字母序大小,问有哪些字符串可能成为字典序最小的字符串. 我们考虑把这些字符串都塞到\(trie\)树上.之后检索每一个字符串的时候,我们看和他同一层的地方是否有字符,如 ...

  2. BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序

    BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序 题意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最 ...

  3. 洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)

    P3065 [USACO12DEC]第一!First! 题目链接:https://www.luogu.org/problemnew/show/P3065 题目描述 Bessie一直在研究字符串.她发现 ...

  4. [USACO12DEC]第一!First! (Trie树,拓扑排序)

    题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...

  5. Trie树|字典树(字符串排序)

    有时,我们会碰到对字符串的排序,若采用一些经典的排序算法,则时间复杂度一般为O(n*lgn),但若采用Trie树,则时间复杂度仅为O(n). Trie树又名字典树,从字面意思即可理解,这种树的结构像英 ...

  6. BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序

    题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...

  7. BZOJ4383 Pustynia(线段树+拓扑排序)

    线段树优化建图暴力拓扑排序即可.对于已确定的数,拓扑排序时dp,每个节点都尽量取最大值,如果仍与已确定值矛盾则无解.叶子连出的边表示大于号,其余边表示大于等于. #include<iostrea ...

  8. [BZOJ2815][ZJOI2012]灾难 灭绝树+拓扑排序+lca

    灾难 [问题描述] 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那 么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的 生态灾难. 学过 ...

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

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

随机推荐

  1. 六、springboot 简单优雅是实现短信服务

    前言 上一篇讲了 springboot 集成邮件服务,接下来让我们一起学习下springboot项目中怎么使用短信服务吧. 项目中的短信服务基本上上都会用到,简单的注册验证码,消息通知等等都会用到.所 ...

  2. 引入外部js

    引入外部js应该使用完整标签<script></script>,而使用单标签<script src=“”/>是错误的

  3. 编译安装msyql

    环境: ubuntu18.04.2 mysql5.7.21 #创建mysql属组 groupadd mysql useradd -g mysql mysql #查看属组 tail /etc/passw ...

  4. 如何编译和调试Python内核源码?

    目录 写在前面 获取源代码 源代码的组织 windows下编译CPython 调试CPython 小结 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 如果对Pyth ...

  5. 【TencentOS tiny】深度源码分析(7)——事件

    引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xx ...

  6. js 判断对象是否为空

    利用JSON.stringify var objData = {};JSON.stringify(objData) ==="{}" // true 第二种用原声js 方法 Obje ...

  7. BZOJ 4392 卡牌游戏

    Description 奶牛贝茜是卡牌游戏的狂热爱好者, 但是令人吃惊的, 她缺乏对手. 不幸的是, 任何牧 群里的其他牛都不是好对手. 他们实在是太差了 , 实际上, 他们玩卡牌游戏时会遵循一种完全 ...

  8. Windows系统调用中API从3环到0环(上)

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中API从3环到0环(上) 如果对API在三 ...

  9. POWERUP攻击渗透实战2

    准备环境: kali linux 攻击机 已获得靶机meterpreter(非管理)权限 win7 靶机  拥有powershell环境 运用到的模块:Get-RegistryAlwaysInstal ...

  10. 浏览器渗透框架BeEF使用笔记(二)

    0x03 常用模块 1-信息收集 可以收集到例如 浏览器名称版本 浏览器用户版本 插件(包括Java,ActiveX,VBS,Flash……) 窗口大小 1)details面板收集 (2)插件收集信息 ...