wannafly 练习赛11 B 假的字符串(字典树+建边找环)

链接:https://www.nowcoder.com/acm/contest/59/B

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

给定n个字符串,互不相等,你可以任意指定字符之间的大小关系(即重定义字典序),求有多少个串可能成为字典序最小的串,并输出它们

输入描述:

第一行一个数表示n
之后n行每行一个字符串表示给定的字符串

输出描述:

第一行输出一个数x表示可行的字符串个数
之后输出x行,每行输出一个可行的字符串
输出的顺序和输入的顺序一致
示例1

输入

6
mcfx
ak
ioi
wen
l
a

输出

5
mcfx
ioi
wen
l
a

备注:

对于100%的数据,
n <= 30000 , 字符串总长<= 300000
字符集为小写字符
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
 1 #include <bits/stdc++.h>
 2 #define mst(a,b)    memset((a),(b), sizeof a)
 3 #define lowbit(a)   ((a)&(-a))
 4 #define IOS         ios::sync_with_stdio(0);cin.tie(0);
 5 using namespace std;
 6 typedef long long ll;
 7 const int mod=1e9+7;
 8 const int maxn=3e5+100;
 9 string use[30010];
10 int head,cnt;
11 int nx[maxn][28];
12 int cc[maxn];
13 bool co[maxn];
14 void init(int k){
15     int now=head;
16     int sz=use[k].size();
17     for(int i=0;i<sz;++i){
18         int d=use[k][i]-'a';
19         if(!nx[now][d])nx[now][d]=++cnt;
20         now=nx[now][d];
21     }
22     ++cc[now];
23 }
24 bool mp[26][26];
25 int vis[26];
26 bool dfs(int pos){
27     vis[pos]=-1;
28     for(int i=0;i<26;++i)if(i!=pos&&mp[pos][i]){
29         if(!vis[i]){
30             if(!dfs(i))return false;
31         }else{
32             if(vis[i]==-1)return false;
33         }
34     }
35     vis[pos]=1;
36     return true;
37 }
38 bool ok(int k){
39     int now=head;
40     int sz=use[k].size();
41     mst(mp,0);mst(vis,0);
42     for(int i=0;i<sz;++i){
43         int d=use[k][i]-'a';
44         for(int j=0;j<26;++j)if(j!=d&&nx[now][j]){
45             mp[j][d]=1;
46         }
47         now=nx[now][d];
48         if(i!=sz-1&&cc[now])return false;
49     }
50     for(int i=0;i<26;++i)if(!vis[i]&&!dfs(i))return false;
51     return true;
52 }
53 int main(){
54 #ifdef local
55 freopen("in.txt","r",stdin);
56 //freopen("out.txt","w",stdout);
57 #endif
58     IOS
59     int n;cin>>n;
60     for(int i=1;i<=n;++i){
61         cin>>use[i];
62         init(i);
63     }
64     int ans=0;
65     for(int i=1;i<=n;++i)if(ok(i)){
66         co[i]=true;
67         ++ans;
68     }
69     cout<<ans<<endl;
70     for(int i=1;i<=n;++i)if(co[i])cout<<use[i]<<endl;
71     return 0;
72 }

 

posted on 2018-02-25 21:14  scau_bi  阅读(148)  评论(0编辑  收藏  举报

导航