【BZOJ3012】[Usaco2012 Dec]First! Trie树+拓补排序
【BZOJ3012】[Usaco2012 Dec]First!
Description
Bessie has been playing with strings again. She found that by changing the order of the alphabet she could make some strings come before all the others lexicographically (dictionary ordering). For instance Bessie found that for the strings "omm", "moo", "mom", and "ommnom" she could make "mom" appear first using the standard alphabet and that she could make "omm" appear first using the alphabet "abcdefghijklonmpqrstuvwxyz". However, Bessie couldn't figure out any way to make "moo" or "ommnom" appear first. Help Bessie by computing which strings in the input could be lexicographically first by rearranging the order of the alphabet. To compute if string X is lexicographically before string Y find the index of the first character in which they differ, j. If no such index exists then X is lexicographically before Y if X is shorter than Y. Otherwise X is lexicographically before Y if X[j] occurs earlier in the alphabet than Y[j].
Input
* Line 1: A single line containing N (1 <= N <= 30,000), the number of strings Bessie is playing with.
* Lines 2..1+N: Each line contains a non-empty string. The total number of characters in all strings will be no more than 300,000. All characters in input will be lowercase characters 'a' through 'z'. Input will contain no duplicate strings.
Output
* Line 1: A single line containing K, the number of strings that could be lexicographically first.
* Lines 2..1+K: The (1+i)th line should contain the ith string that could be lexicographically first. Strings should be output in the same order they were given in the input.
Sample Input
omm
moo
mom
ommnom
INPUT DETAILS: The example from the problem statement.
Sample Output
omm
mom
OUTPUT DETAILS: Only "omm" and "mom" can be ordered first.
题解:先将单词都塞到Trie树里,然后考虑如果想让一个单词排在最前面,首先它肯定不能包含其他单词(这点卡了我很久)
然后我们在Trie树里遍历这个单词对应的链,如果想让这个链排在最前面,只需要让链上每个节点的排序都比它的兄弟靠前(同父的兄弟),最后处理出所有大小关系,跑一个拓补排序判环就行了
我到官网查了数据,发现所有单词的长度都不超过20,所以不用担心空间的问题
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int maxn=300010;
int n,tot,cnt,ans,sum;
int ch[maxn][26],num[maxn],can[30010],head[30],next[1000],to[1000],len[30010],d[30];
queue<int> q;
char str[30010][50];
void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
int main()
{
scanf("%d",&n);
int i,j,k,u;
for(i=1;i<=n;i++)
{
scanf("%s",str[i]);
len[i]=strlen(str[i]);
u=0;
for(j=0;j<len[i];j++)
{
if(!ch[u][str[i][j]-'a']) ch[u][str[i][j]-'a']=++tot;
u=ch[u][str[i][j]-'a'];
}
if(!num[u]) num[u]=i,can[i]=1;
}
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++)
{
if(!can[i]) continue;
memset(head,-1,sizeof(head)),memset(d,0,sizeof(d));
sum=cnt=u=0;
for(j=0;j<len[i];j++)
{
if(num[u])
{
can[i]=0;
break;
}
for(k=0;k<26;k++) if(k!=str[i][j]-'a'&&ch[u][k]) d[k]++,add(str[i][j]-'a',k);
u=ch[u][str[i][j]-'a'];
}
if(!can[i]) continue;
for(j=0;j<26;j++) if(!d[j]) q.push(j);
while(!q.empty())
{
u=q.front(),q.pop(),sum++;
for(j=head[u];j!=-1;j=next[j])
{
d[to[j]]--;
if(!d[to[j]]) q.push(to[j]);
}
}
if(sum<26) can[i]=0;
else ans++;
}
printf("%d\n",ans);
for(i=1;i<=n;i++) if(can[i]) printf("%s\n",str[i]);
return 0;
}
【BZOJ3012】[Usaco2012 Dec]First! Trie树+拓补排序的更多相关文章
- BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序
BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序 题意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最 ...
- 【BZOJ3036】绿豆蛙的归宿 拓补排序+概率
[BZOJ3036]绿豆蛙的归宿 Description 随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度. ...
- [USACO11JAN]Roads and Planes G【缩点+Dij+拓补排序】
题目 Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条道路 (1 < ...
- BZOJ 3012: [Usaco2012 Dec]First! 字典树 + tarjan
Code: #include<bits/stdc++.h> #define maxn 1000003 using namespace std; char str[maxn],strtot[ ...
- BZOJ3012 : [Usaco2012 Dec]First!
建立Trie,那么成为答案的串必须满足其终止节点到根路径上没有其它点. 对于Trie上每个节点维护一个bitset,表示哪些字符必须在哪些字符之前. 每到达一个可能成为答案的终止节点,对图进行拓扑排序 ...
- bzoj 3012: [Usaco2012 Dec]First! Trie+拓扑排序
题目大意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最小的串,并输出这些串.n <= 30,000 , m <= 300,0 ...
- HDU 1811 Rank of Tetris 拓补排序+并查集
Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) [ ...
- poj 3687 Labeling Balls(拓补排序)
Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them ...
- poj 1094 Sorting It All Out 拓补排序
Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...
随机推荐
- sed删除空行和开头的空格和tab键
[root@ob1 scripts]# cat -An tt2.txt 1 jeyry$ 2 ^I$ 3 jfdkjfdjk$ 4 ^Ikjfdkjfdkj ...
- iOS边练边学--view的封装
一.view封装的思路: *如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部的子控件的创建屏蔽起来,不让外界关心 *外界可以传入对应的模型数据给view,view拿到模型数据 ...
- Linux C定时器使用指南
使用定时器的目的是为了周期性的执行某一任务,或者是到了某个指定时间去执行某一任务.要达到这一目的,一般有两个常见的方法.一个是用linux内部的三个定时器,另一个是用sleep, usleep函数让进 ...
- Node.js获取mac网卡地址
一.关于getmac node.js没有直接获取mac网卡地址的模块,此时我们需要借助于第三方模块getmac.getmac 可以帮助我们 获取当前机器上的mac地址.gatmac 下载地址为:htt ...
- Rattle:数据挖掘的界面化操作
R语言是一个自由.免费.源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具.这里的统计计算可以是数据分析.建模或是数据挖掘等,通过无数大牛提供的软件包,可以帮我们轻松实现算法的实施. 一些读者 ...
- tensorflow中slim模块api介绍
tensorflow中slim模块api介绍 翻译 2017年08月29日 20:13:35 http://blog.csdn.net/guvcolie/article/details/77686 ...
- pip 安装库过慢
对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太慢,浪费时间.而且经常出现下载后安装出错问题. 所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装 ...
- android项目中的拍照和本地图片截图
1,得到保存截图文件的地址 private static final String IMAGE_FILE_LOCATION = Environment.getExternalStorageDirect ...
- Python中tab键自动补全功能的配置
新手学习Python的时候,如何没有tab键补全功能,我感觉那将是一个噩梦,对于我们这种菜鸟来说,刚接触python,对一切都不了解,还好有前辈们的指导,学习一下,并记录下来,还没有学习这个功能小伙伴 ...
- ueditor1_4_3_3编辑器的应用
教程使用的是ueditor1_4_3_3版本. 首先到官网http://ueditor.baidu.com/website/download.html下载jsp utf-8版 下载好以后,解压,把解 ...