[BZOJ]3012: [Usaco2012 Dec]First! trie树+拓扑排序
题解: 首先可以知道 某一个串存在前缀串则这个串必然不能字典序最小 所以我们直接对长度排序然后逐次加入trie树中 然后我们考虑当前串能成为最小 必须一层层满足对应的限制条件 然后拓扑check一下就行了
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <string> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=3e5+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t;edge*next;}e[905],*h[26],*o=e; void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } typedef struct node{ int id;string s; }node; node str[MAXN]; bool cmp(node aa,node bb){return aa.s.length()<bb.s.length();} typedef struct Node{ int ch[26],sz,id; }Node; Node d[MAXN]; int rt,cnt; void newnode(int &x){ x=++cnt; d[x].sz=d[x].id=0; for(int i=0;i<26;i++)d[x].ch[i]=0; } void insert(string s,int id){ int len=s.length();int temp=rt; bool flag=0; for(int i=0;i<len;i++){ int t=s[i]-'a'; if(!d[temp].ch[t]){break;} temp=d[temp].ch[t]; if(d[temp].id){flag=1;break;} } if(flag)return ; temp=rt; for(int i=0;i<len;i++){ int t=s[i]-'a'; if(!d[temp].ch[t])newnode(d[temp].ch[t]); temp=d[temp].ch[t];d[temp].sz++; } d[temp].id=id; } int Edge[31][31]; bool vis[MAXN]; int du[MAXN],ans1; queue<int>que; bool check(){ inc(i,0,25)if(!du[i])que.push(i); while(!que.empty()){ int x=que.front();que.pop(); link(x){ du[j->t]--; if(!du[j->t])que.push(j->t); } } inc(i,0,25)if(du[i])return 0; return 1; } void dfs(int x){ if(d[x].id){ memset(h,0,sizeof(h));o=e; inc(i,0,25)du[i]=0; inc(i,0,25)inc(j,0,25)if(Edge[i][j])add(i,j),du[j]++; if(check())vis[d[x].id]=1,ans1++; return ; } for(int i=0;i<26;i++){ if(!d[x].ch[i])continue; for(int j=0;j<26;j++){ if(j!=i&&d[x].ch[j])Edge[i][j]++; } dfs(d[x].ch[i]); for(int j=0;j<26;j++){ if(j!=i&&d[x].ch[j])Edge[i][j]--; } } } string S[MAXN]; int main(){ ios::sync_with_stdio(false); ans1=0; int n;cin>>n; inc(i,1,n)cin>>str[i].s,str[i].id=i,S[i]=str[i].s; sort(str+1,str+n+1,cmp); inc(i,1,n)insert(str[i].s,str[i].id); dfs(rt); cout<<ans1<<"\n"; inc(i,1,n)if(vis[i])cout<<S[i]<<"\n"; }
3012: [Usaco2012 Dec]First!
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 328 Solved: 159
[Submit][Status][Discuss]
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.
Sample Input
omm
moo
mom
ommnom
INPUT DETAILS: The example from the problem statement.
Sample Output
omm
mom
OUTPUT DETAILS: Only "omm" and "mom" can be ordered first.