Description

Luogu3065

Solution

首先,一个串要是最小的,别的串不能是它的前缀,且和它有相同前缀的串字典序都比他小。

Trie树是显然要用的,难点在于如何判断能否最小。其实这之中蕴含了字母间的大小关系,即同一层中,钦定的最小串的字符要比其它的大。然后就可以建一个有向图跑拓扑排序判环就行。

Code

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <vector> namespace wyx { typedef int ll; ll read() {
ll ans = 0, fl = 1;
char c;
for (c = getchar(); c > '9' || c < '0'; c = getchar())
if (c == '-') fl = -1;
ans = c - '0';
for (c = getchar(); c >= '0' && c <= '9'; c = getchar())
ans = ans * 10 + c - '0';
return fl * ans;
} typedef double ld;
typedef unsigned long long ull;
const int N = 30010; struct Trie {
int to[N * 10][26], cnt, val[N * 10];
Trie() {
memset(to, 0, sizeof to);
memset(val, 0, sizeof val);
cnt = 0;
}
void add(const std::string& s) {
int len = s.length();
int now = 0;
for (int i = 0; i < len; ++i) {
if (!to[now][s[i] - 'a']) to[now][s[i] - 'a'] = ++cnt;
now = to[now][s[i] - 'a'];
}
val[now]++;
}
} Tr;
struct Graph {
std::vector<int> g[26];
int deg[26];
void init() {
for (int i = 0; i < 26; ++i) g[i].clear(), deg[i] = 0;
}
void adde(int x, int y) {
g[x].push_back(y);
deg[y]++;
}
bool toposort() {
std::queue<int> q;
for (int i = 0; i < 26; ++i)
if (deg[i] == 0) q.push(i);
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i : g[x])
if (--deg[i] == 0) q.push(i);
}
for (int i = 0; i < 26; ++i)
if (deg[i]) return false;
return true;
}
} G;
std::string s[N];
int n, vis[N]; bool work(int x) {
int now = 0, len = s[x].length();
for (int i = 0; i < len; ++i) {
if (Tr.val[now]) return false;
for (int j = 0; j < 26; ++j) {
if (j != s[x][i] - 'a' && Tr.to[now][j]) G.adde(s[x][i] - 'a', j);
}
now = Tr.to[now][s[x][i] - 'a'];
}
return true;
} void main() {
n = read();
for (int i = 1; i <= n; ++i) std::cin >> s[i], Tr.add(s[i]);
int cnt = 0;
for (int i = 1; i <= n; ++i) {
G.init();
if (work(i) && G.toposort()) {
vis[i] = 1;
cnt++;
}
}
printf("%d\n", cnt);
for (int i = 1; i <= n; ++i)
if (vis[i]) {
std::cout << s[i] << std::endl;
}
} }; // namespace wyx int main() {
wyx::main();
return 0;
}

最新文章

  1. IE10/11克隆textarea时 bug
  2. js 作用域
  3. 最全面的NSDateHelper 分享
  4. 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
  5. IOS开发UI基础UIImageView属性属性
  6. 【ASP.NET MVC 】让@Ajax.ActionLink获取的数据不进Cache
  7. date用法
  8. IOS_多线程_ASI_AFN_UIWebView
  9. javascript 欺骗词法作用域
  10. salesforce lightning零基础学习(二) lightning 知识简单介绍----lightning事件驱动模型
  11. python复习1
  12. 2018蓝桥杯 省赛D题(测试次数)
  13. @ResponseBody//该注解会将返回值转为json格式并放到响应体中返回到前台
  14. 菜鸟入门【ASP.NET Core】5:命令行配置、Json文件配置、Bind读取配置到C#实例、在Core Mvc中使用Options
  15. python调用ansible接口API执行命令
  16. The Real Meaning of Peace
  17. 三年Linux运维工作总结教训
  18. 最简单的rman操作
  19. matplotlib绘制散点图
  20. 【Java实战】源码解析为什么覆盖equals方法时总要覆盖hashCode方法

热门文章

  1. 1.3.5 详解项目中的资源——Android第一行代码(第二版)笔记
  2. 「Flink」Flink中的时间类型
  3. 什么是AOP面向切面编程思想
  4. ts中的装饰器
  5. 【DTOJ】2704:数字互换
  6. vue 3.0 项目搭建移动端 (六) 命名路由同级控制
  7. python3练习100题——002
  8. 10maven依赖继承、统一版本/编码
  9. PostgreSQL内核学习笔记十一(索引)
  10. 【Git】git使用 - 各种常用场景命令解决