BZOJ 3012: [Usaco2012 Dec]First! 字典树 + tarjan
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.
题解: 比较简单的一道题吧,考试的时候大家都几乎一眼切.
将所有串插进字典树
依次枚举每个串,将其定义为字典序最小的串.
那么,就要满足对于字典树中每一个分叉,必须保证当前串该字符大小要小于该分叉其余所有字符.
那么,这样就构建出了一些大小关系.
如果大小关系出现了环,说明无解.
我是用 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的更多相关文章
- bzoj 3012: [Usaco2012 Dec]First! Trie+拓扑排序
题目大意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最小的串,并输出这些串.n <= 30,000 , m <= 300,0 ...
- BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序
BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序 题意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典序最 ...
- BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )
子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 -------------------------------------------------------------- ...
- 【BZOJ3012】[Usaco2012 Dec]First! Trie树+拓补排序
[BZOJ3012][Usaco2012 Dec]First! Description Bessie has been playing with strings again. She found th ...
- BZOJ 1212 L语言(DP+字典树)
求能被理解的最长前缀. 很显然的dp.令dp[i]=true,表示前缀i能理解.否则不能理解.那么dp[i+len]=dp[i]=true,当s[len]能匹配str[i,i+len]. 由于模式串长 ...
- BZOJ 4260 Codechef REBXOR(字典树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4260 [题目大意] 给出一个数列,请找出两段连续且不相交的数段,使得其分别异或和的和 ...
- 「Usaco2012 Dec」第一(字典树+拓扑排序)
(我恨字符串) 惯例化简题目:给定n个字符串,可以改变字符的相对大小(在字典序中的大小),问:字符串i是否能成为最小的字符串(字典序) 解题过程: 首先你可以预处理出来26的全排列然后暴力然后你只要用 ...
- BZOJ 4260 Codechef REBXOR (区间异或和最值) (01字典树+DP)
<题目链接> 题目大意:给定一个序列,现在求出两段不相交的区间异或和的最大值. 解题分析: 区间异或问题首先想到01字典树.利用前缀.后缀建树,并且利用异或的性质,相同的两个数异或变成0, ...
- BZOJ 3483 SGU505 Prefixes and suffixes(字典树+可持久化线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3483 [题目大意] 给出一些串,同时给出m对前缀后缀,询问有多少串满足给出的前缀后缀模 ...
随机推荐
- Spell checker POJ 1035 字符串
Spell checker Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25426 Accepted: 9300 De ...
- Findbug插件静态java代码扫描工具使用
本文转自http://blog.csdn.net/gaofuqi/article/details/22679609 感谢作者 FindBugs 是由马里兰大学提供的一款开源 Java静态代码分析工具. ...
- 在shell脚本中使用函数的返回值
#!/bin/bash - function mytest() { echo "arg1 = $1" if [ $1 = "1" ] ;then return ...
- oracle 学习笔记之触发器
说明 数据库触发器是一个与表相关联的.存储的PL/SQL程序. 每当一个特定的数据操作语句(Insert,update,delete)在指定的表上发出时,Oracle自己主动地运行触发器中定义的语句序 ...
- Linux/CentOS各种服务框架的搭建完整流程
在2012年的时候,由于要照应新人对Linux以及相关服务的了解和学习,我特地把当时我们创业项目的全部服务搭建过程写成了一篇文档,能够让他们学习而且有所參照. 以下就以这篇文档为底稿,进行一些改动和敏 ...
- Bag标签之删除书包中的一条数据
删除书包中的一条数据 查询 <esql module=help id=list> Select ID,Subject,Writer,DayTime From Messages </e ...
- Fiddler手机抓包工具设置过滤域名
需求:我想用fiddler抓包只抓test.sis.1course.cn; pre.schoolis.cn; sistest02.schoolis.cn;这几个域名下的请求 设置步骤:https:// ...
- SpringMVC + hibernate 配置文件
web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="htt ...
- 【Ubuntu QQ】记如何在Ubuntu上安装QQ(附下载)
什么困扰着一批批的ubuntu桌面用户?是麻花藤.哦不,是QQ,怎么在ubuntu上安装完美无瑕的QQ. 最佳解决方案在“三”部分,当然前两个也不失为解决方案 一.尝试的开始 配置: 双系统:Wind ...
- elasticsearch _field_stats 源码分析
_field_stats 实现的功能:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-field-stats.ht ...