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. nyoj_111_分数加减法_201311281341

    分数加减法 时间限制:3000 ms  |           内存限制:65535 KB 难度:2   描述 编写一个C程序,实现两个分数的加减法   输入 输入包含多行数据 每行数据是一个字符串, ...

  2. OGNL是什么

    OGNL表达式是(Object-Graph Navigation Language)是对象图形化导航语言.OGNL是一个开源的项目,Struts2中默认使用OGNL表达式语言来显示数据.与Serlve ...

  3. Clojure:解决Selmer与AngularJS的 标签混淆问题

    Selmer是Clojure的一个模板类库,下面是它的一个DEMO模板: <ul> {% for item in items %} <li>{{item}}</li> ...

  4. 阿里2016实习offer五面经验与总结

    前言 眼下楼主已经拿到阿里实习offer,一共经历了5次面试,当中4轮技术面.1轮HR面试.在这里分享一下自己的面试经验和学习总结.写这篇面经主要是希望可以帮助很多其它的小伙伴.我本科毕业于中南大学信 ...

  5. 20170322js面向对象

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. 利用html sessionStorge 来保存局部页面在刷新后回显,保留

    转自:https://blog.csdn.net/u011085172/article/details/77320562 在一个页面里面,有个局部页面记录这当前session的任务记录,之前用的coo ...

  7. (Go)07.strings与strconv的示例

    package main import ( "strconv" "fmt" "strings" ) func main() { str := ...

  8. PCB 无需解压,直接读取Zip压缩包指定文件 实现方法

    最近有一项需求,将电测试点数后台批量写入到工程系统流程指示中,而电测试文件存在压缩包中,压缩包存在公共网络盘 示例图: 一.采用原始方法(4步完成): 第1步:.网络盘ZIP拷到本地, 第2步:解压Z ...

  9. ASP.NET Core 多环境

    ASP.NET Core 支持在多个环境中管理应用程序,如开发(Development),预演(Staging)和生产(Production).环境变量用来指示应用程序正在运行的环境,允许应用程序适当 ...

  10. Oracle_exp/expdp备份

    目录索引 1.exp和expdp的区别 2.expdp导出数据库流程 一.↓↓exp和expdp的区别↓↓ 1.exp和expdp最明显的区别就是导出速度的不同.expdp导出是并行导出(如果把exp ...