码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3012 : [Usaco2012 Dec]First!

时间:2015-11-07 06:10:32      阅读:327      评论:0      收藏:0      [点我收藏+]

标签:

建立Trie,那么成为答案的串必须满足其终止节点到根路径上没有其它点。

对于Trie上每个节点维护一个bitset,表示哪些字符必须在哪些字符之前。

每到达一个可能成为答案的终止节点,对图进行拓扑排序进行判定。

时间复杂度$O(26^2N+26|S|)$。

 

#include<cstdio>
#include<cstring>
#define rep(i) for(int i=0;i<26;i++)
const int N=30010,M=300010;
int n,i,j,k,x,cnt,len,st[N],en[N],fin[N],ans;
int tot,son[M][26],id[M],v[M],f[M][26];
int g[26][26],d[26],q[30];
char s[M],text[M];
void dfs(int x){
  if(id[x]){
    rep(i)for(int j=d[i]=0;j<26;j++)g[i][j]=0;
    rep(i)rep(j)if(i!=j&&(f[x][i]>>j&1))g[i][j]=1,d[j]++;
    int h=1,t=0;
    rep(i)if(!d[i])q[++t]=i;
    while(h<=t){
      int x=q[h++];
      rep(i)if(g[x][i])if(!(--d[i]))q[++t]=i;
    }
    if(t==26)fin[id[x]]=1,ans++;
    return;
  }
  rep(i)if(son[x][i]){
    int y=son[x][i];
    rep(j)f[y][j]=f[x][j];
    f[y][i]|=v[x];
    dfs(y);
  }
}
int main(){
  scanf("%d",&n);
  for(i=1;i<=n;i++){
    scanf("%s",s);
    len=strlen(s);
    st[i]=cnt;
    for(j=x=0;j<len;x=son[x][k],j++)if(!son[x][k=text[cnt++]=s[j]-‘a‘])son[x][k]=++tot,v[x]|=1<<k;
    id[x]=i;
    en[i]=cnt;
  }
  dfs(0);
  for(printf("%d\n",ans),i=1;i<=n;i++)if(fin[i]){
    for(j=st[i];j<en[i];j++)putchar(text[j]+‘a‘);
    puts("");
  }
  return 0;
}

  

BZOJ3012 : [Usaco2012 Dec]First!

标签:

原文地址:http://www.cnblogs.com/clrs97/p/4944061.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!