【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 ...
随机推荐
- lvm 新建一个vg 逻辑卷 配置启动
fdisk /dev/sdb 格式 t 8e w vgcreate datavg /dev/sdb1lvcreate -L 999G -n lvdata datavgmkfs.xfs /dev/da ...
- BeamNG.drive物理引擎评鉴
BeamNG.drive是一款由BeamNG公司开发并于2013年首次发布的软体物理模拟游戏.作为模拟游戏,特别是物理模拟的粉丝,我早早就开始使用BeamNG.drive.我立即对崩溃的准确性和细节印 ...
- 实现整数转化为字符串函数itoa()函数
函数原型: char *itoa( int value, char *string,int radix);原型说明:value:欲转换的数据.string:目标字符串的地址.radix:转换后的进制数 ...
- MySql C++调用库Connector/c++编译 和 接口封装【一】mysql数据库安装
Connector/c++库的源文件编译,你需要先准备好以下工具: mysql数据库(编译时要依赖),boost库,cmake(生成sln工程文件),connector/c++的源文件,vis ...
- SQL SERVER 2005快捷键
一.SQL SERVER 2005快捷键 快捷键 功能 CTRL + SHIFT + B生成解决方案 CTRL + F7 生成编译 CTRL + O 打开文件 CTRL + SHIFT + O打开项目 ...
- relation 关联模型
关联关系必然有一个参照表,例如:有一个员工档案管理系统项目,这个项目要包括下面的一些数据表:基本信息表.员工档案表.部门表.项目组表.银行卡表(用来记录员工的银行卡资料).这些数据表之间存在一定的关联 ...
- 关于Unity中UI中的Mask组件、Text组件和布局
一.Mask组件 遮罩,Rect Mask矩形Mask(Rect Mask2D组件),图片Mask(Mask组件)(图片Mask的透明度不为0的部分显示子图片,为0的部分不显示子图片) Rect Ma ...
- DOM编程 学习笔记(一)
PS:虽然自己JS基本语法算是掌握了,但是其实在JS掌握的只是远远还不够,网页上有太多好看的动态效果都是用JS 做出来的,自己也就仅仅会那么一两个动态的效果,学的只是皮毛...等有空的时候一定要好好的 ...
- 在 Mac 上搭建 Nginx PHP Mysql 开发环境
事实上这个过程跟Linux下安装都几乎相同,仅仅是部分命令有区别,大同小异. 网上看到非常多教程都是用 brew 之类的包管理器安装,可是 Mac 自带了 php , 难道还要再装一个第三方的?强迫症 ...
- JavaSE(八)集合之Set
今天这一篇把之前没有搞懂的TreeSet中的比较搞得非常的清楚,也懂得了它的底层实现.希望博友提意见! 一.Set接口 1.1.Set集合概述 Set集合:它类似于一个罐子,程序可以依次把多个对象 “ ...