[USACO12DEC]First!
阿新 • • 發佈:2018-10-31
Description
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; }