usaco dec 2012 first!

字典树加拓扑排序

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<iostream>
  5 #include<vector>
  6 using namespace std;
  7 const int  maxnode=300000+5;
  8 const int maxn=30000+5;
  9 struct Trie
 10 {
 11   int ch[maxnode][26];
 12   int pre[maxnode];
 13   int val[maxnode];
 14   string s[maxn];
 15   int terminal[maxn];
 16   int sz;
 17   int n;
 18   void insert(string str,int v)
 19   {
 20       int len=str.length();
 21       int u=0;
 22       for(int i=0;i<len;i++)
 23       {
 24           int c=str[i]-'a';
 25           if(!ch[u][c])
 26           {
 27               memset(ch[sz],0,sizeof(ch[sz]));
 28               ch[u][c]=sz++;
 29           }
 30           pre[ch[u][c]]=u;
 31           u=ch[u][c];
 32       }
 33        val[u]++;
 34       terminal[v]=u;
 35   }
 36   void initial()
 37   {
 38       sz=1;
 39       memset(ch[0],0,sizeof(ch[0]));
 40       memset(val,0,sizeof(val));
 41       memset(pre,0,sizeof(pre));
 42       scanf("%d",&n);
 43      for(int i=0;i<n;i++)
 44      {
 45         cin>>s[i];
 46         insert(s[i],i);
 47      }
 48   }
 49   bool check(int *cnt,vector<int> g[])
 50   {
 51       int top=-1;
 52       bool bcycle=false;
 53      for(int i=0;i<26;i++)
 54      {
 55          if(cnt[i]==0)
 56          {
 57              cnt[i]=top;
 58              top=i;
 59          }
 60      }
 61      for(int i=0;i<26;i++)
 62      {
 63          if(top==-1) {bcycle=true;break;}
 64          else
 65          {
 66              int j=top;top=cnt[top];
 67              for(int k=0;k<g[j].size();k++)
 68              {
 69                  int u=g[j][k];
 70                  if(--cnt[u]==0)
 71                  {
 72                      cnt[u]=top;
 73                      top=u;
 74                  }
 75              }
 76          }
 77      }
 78      if(bcycle) return false;
 79      return true;
 80   }
 81   void solve()
 82   {
 83       initial();
 84       vector<int> g[27];
 85       int cnt[27];
 86       int ans[n];
 87       memset(ans,0,sizeof(ans));
 88       int tot=0;
 89       for(int i=0;i<n;i++)
 90       {
 91           for(int j=0;j<26;j++) g[j].clear();
 92           memset(cnt,0,sizeof(cnt));
 93           int cur=terminal[i];
 94           int flag=1;
 95           for(int j=s[i].length()-1;j>=0;j--)
 96           {
 97               int c=s[i][j]-'a';
 98               cur=pre[cur];
 99               if(val[cur]) flag=0;
100               for(int k=0;k<26;k++)
101               {
102                   if(ch[cur][k]&&k!=c)
103                   {
104                       g[c].push_back(k);
105                       cnt[k]++;
106                   }
107               }
108           }
109           if(flag&&check(cnt,g)) {tot++;ans[i]=1;}
110       }
111       printf("%d\n",tot);
112       for(int i=0;i<n;i++)
113       {
114           if(ans[i]) cout<<s[i]<<endl;
115       }
116   }
117 };
118 Trie trie;
119 int main()
120 {
121    //freopen("24123.in","r",stdin);
122    //freopen("24123.out","w",stdout);
123     trie.solve();
124 }

posted @ 2013-10-20 00:18  sooflow  阅读(245)  评论(0)    收藏  举报