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].

给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系。问有多少个串可能成为字典
序最小的串,并输出这些串。n <= 30,000 , m <= 300,000

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.

题解: 比较简单的一道题吧,考试的时候大家都几乎一眼切.
将所有串插进字典树
依次枚举每个串,将其定义为字典序最小的串.
那么,就要满足对于字典树中每一个分叉,必须保证当前串该字符大小要小于该分叉其余所有字符.
那么,这样就构建出了一些大小关系.
如果大小关系出现了环,说明无解.
我是用 tarjan 找环来判断的.

#include<bits/stdc++.h>
#define maxn 1000003
using namespace std;
char str[maxn],strtot[maxn];
int lentot,scc,flag,pp=0;
int st[maxn],ed[maxn],C[30][30],vis[maxn],vised[maxn],pre[maxn],low[maxn];
void setIO(string s)
{
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
vector<int>G[maxn],answer,tag[maxn];
stack<int>S;
struct Trie
{
int cnt;
int ch[maxn][30];
void ins(char p[],int o)
{
int len=strlen(p+1),cur=0;
for(int i=1;i<=len;++i)
{
int c=p[i]-'a';
if(!ch[cur][c])
{
ch[cur][c]=++cnt;
G[cur].push_back(c);
}
cur=ch[cur][c];
}
tag[cur].push_back(o);
}
}trie;
void tarjan(int u)
{
S.push(u);
vised[u]=1;
pre[u]=low[u]=++scc;
for(int i=0;i<27;++i)
{
if(u==i || !vis[i] || !C[u][i]) continue;
if(!vised[i]) tarjan(i), low[u]=min(low[u], low[i]);
else if(vised[i]==1) low[u]=min(low[u],pre[i]);
}
if(low[u]==pre[u])
{
int cc=0;
for(;;)
{
int x=S.top();S.pop();
++cc;
vised[x]=-1;
if(cc>1) flag=1;
if(x==u) break;
}
} }
bool check()
{
flag=scc=0;
while(!S.empty())S.pop();
for(int i=0;i<27;++i) vised[i]=low[i]=pre[i]=0;
for(int i=0;i<27;++i)
{
if(!vis[i]) continue;
if(!vised[i]) tarjan(i);
}
return flag^1;
}
void dfs(int u,int depth)
{
if(tag[u].size())
{
if(check())
{
for(int j=0,sz=tag[u].size();j<sz;++j) answer.push_back(tag[u][j]);
}
return;
}
for(int i=0;i<27;++i)
{
// 有延申出去的单词
if(trie.ch[u][i]) // 当前为 u
{
++vis[i];
int y=u;
for(int j=0,sz=G[u].size();j<sz;++j)
{
if(G[u][j]!=i)
{
++C[i][G[u][j]];
}
}
dfs(trie.ch[u][i],depth+1);
for(int j=0,sz=G[u].size();j<sz;++j)
{
if(G[u][j]!=i) --C[i][G[y][j]];
}
--vis[i];
}
}
}
int main()
{
// setIO("ok");
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%s",str+1);
trie.ins(str,i);
int v=strlen(str+1);
st[i]=lentot+1;
for(int j=1;j<=v;++j) strtot[++lentot]=str[j];
ed[i]=lentot;
}
dfs(0,0);
printf("%d\n",answer.size());
sort(answer.begin(),answer.end());
for(int i=0,sz=answer.size();i<sz;++i)
{
for(int j=st[answer[i]];j<=ed[answer[i]];++j) printf("%c",strtot[j]);
printf("\n");
}
return 0;
}

  

BZOJ 3012: [Usaco2012 Dec]First! 字典树 + tarjan的更多相关文章

  1. bzoj 3012: [Usaco2012 Dec]First! Trie+拓扑排序

    题目大意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最小的串,并输出这些串.n <= 30,000 , m <= 300,0 ...

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

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

  3. BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )

    子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 -------------------------------------------------------------- ...

  4. 【BZOJ3012】[Usaco2012 Dec]First! Trie树+拓补排序

    [BZOJ3012][Usaco2012 Dec]First! Description Bessie has been playing with strings again. She found th ...

  5. BZOJ 1212 L语言(DP+字典树)

    求能被理解的最长前缀. 很显然的dp.令dp[i]=true,表示前缀i能理解.否则不能理解.那么dp[i+len]=dp[i]=true,当s[len]能匹配str[i,i+len]. 由于模式串长 ...

  6. BZOJ 4260 Codechef REBXOR(字典树)

    [题目链接]  http://www.lydsy.com/JudgeOnline/problem.php?id=4260 [题目大意] 给出一个数列,请找出两段连续且不相交的数段,使得其分别异或和的和 ...

  7. 「Usaco2012 Dec」第一(字典树+拓扑排序)

    (我恨字符串) 惯例化简题目:给定n个字符串,可以改变字符的相对大小(在字典序中的大小),问:字符串i是否能成为最小的字符串(字典序) 解题过程: 首先你可以预处理出来26的全排列然后暴力然后你只要用 ...

  8. BZOJ 4260 Codechef REBXOR (区间异或和最值) (01字典树+DP)

    <题目链接> 题目大意:给定一个序列,现在求出两段不相交的区间异或和的最大值. 解题分析: 区间异或问题首先想到01字典树.利用前缀.后缀建树,并且利用异或的性质,相同的两个数异或变成0, ...

  9. BZOJ 3483 SGU505 Prefixes and suffixes(字典树+可持久化线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3483 [题目大意] 给出一些串,同时给出m对前缀后缀,询问有多少串满足给出的前缀后缀模 ...

随机推荐

  1. 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。

    本文转自http://www.cnblogs.com/davidwang456/p/4090058.html 感谢作者 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并 ...

  2. DELPHI RTTI实现非可视的功能插件

    思路:通过数据字典定义BPL包名,然后定义BPL包里面的类名,然后定义类里面的方法名,最后定义方法的参数值. 可实现动态加载BPL,调用哪个BPL的哪个类的哪个方法并给该方法赋给指定的参数值,如果是函 ...

  3. iOS: 在Swift中优雅的实现Substring

    在Swift中,当我们想要截取某个字符串时,方法如下: let carNumber = "沪A12345" let startIndex = advance(userCar.car ...

  4. cocos2d js ClippingNode 制作标题闪亮特效

    1.效果图: 之前在<Android 高仿 IOS7 IPhone 解锁 Slide To Unlock>中制作了文字上闪亮移动的效果,这次我们来看下怎样在cocos2d js 中做出类似 ...

  5. 黑马程序猿——————java基础

    一.软件开发 软件是什么? 软件是简单的来说,计算机数据和指令的集合,数据(比方年龄,性别).指令及时告诉计算机怎样对他进行处理.计算机但是没有人那么聪明啊! 二.图形化界面(GUI),主要特点就是. ...

  6. 严格符合CommonJS规范的包特性

    严格符合CommonJS规范的包应该具备下面特性: 1.package.json必须在包的顶层文件夹下. 2.二进制文件应该在bin文件夹下. 3.JavaScript代码应该在lib文件夹下. 4. ...

  7. Android面试常问的技术问题

    面试时技术经理会问你一些工作中遇到的Android方面的问题.谈谈你所做的项目,和在项目中所扮演的角色. 很多其它内容请參考我的博客:点击打开链接 1.怎样优化ListView? ①Item布局,层级 ...

  8. luogu3084 Photo 单调队列优化DP

    题目大意 农夫约翰决定给站在一条线上的N(1 <= N <= 200,000)头奶牛制作一张全家福照片,N头奶牛编号1到N.于是约翰拍摄了M(1 <= M <= 100,000 ...

  9. 君正Ingenic X1000E_halley2 更改Logo

    有两种方法可以改变开机logo,编译进内核或者修改u-boot. <一>.编译进内核 一. 制作LOGO图片(可以使用gimp) 1. 制作一个.ppm格式图片(logo_tvu_clut ...

  10. bzoj4977 跳伞求生——贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4977 今天讲的贪心题,真神奇啊: 首先,要得到尽量多选队友的解: 把队友按 a[i] 从小到 ...