zoukankan      html  css  js  c++  java
  • 洛谷 P3065 [USACO12DEC]First! G(字典树,环的判断)

    传送门


    解题思路

    先用字典树存储所有的字符串,然后对每个字符串进行判断是否能成为符合要求的字符串:

    对于这个字符串的每一位,如果这一位上有别的字符串与之不同,那么一定就把别的字符串这一位上对应的字符j这个字符串这一位上对应的字符t连一条边,表示我们规定的字母表中j大于t。

    然后判断有没有环出现即可。

    注意dfs要每查一次要清空(代码中),否则会挂,比如A->B,A->B->C。

    当然拓扑也行……

    AC代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<iomanip>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=30005;
     8 string s[maxn];
     9 int ch[maxn*10][30],vis[maxn*10],cnt=1,n,en[maxn*10],num,ans[maxn];
    10 bool dayu[30][30],vis3[30];
    11 void insert(int id){
    12     int len=s[id].length(),now=1;
    13     for(int i=0;i<len;i++){
    14         if(!ch[now][s[id][i]-'a']) ch[now][s[id][i]-'a']=++cnt;
    15         now=ch[now][s[id][i]-'a'];
    16         vis[now]++;
    17     }
    18     en[now]++;
    19 }
    20 bool dfs(int u){
    21     if(vis3[u]) return 0;
    22     vis3[u]=1;
    23     for(int i=0;i<=25;i++){
    24         if(u==i) continue;
    25         if(!dayu[u][i]) continue;
    26         if(!dfs(i)) return 0;
    27     }
    28     vis3[u]=0;//注意 
    29     return 1;
    30 }
    31 bool query(int id){
    32     memset(dayu,0,sizeof(dayu));
    33     memset(vis3,0,sizeof(vis3));
    34     int len=s[id].length(),now=1;
    35     for(int i=0;i<len;i++){
    36         if(en[now]) return 0;
    37         int t=s[id][i]-'a';
    38         for(int j=0;j<=25;j++){
    39             if((j!=t)&&ch[now][j]){
    40                 if(dayu[t][j]) return 0;
    41                 else dayu[j][t]=1;
    42             }
    43         }
    44         now=ch[now][s[id][i]-'a'];
    45         if(vis[now]==1) break;
    46     }
    47     for(int i=0;i<=25;i++) if(!vis3[i]&&!dfs(i)) return 0;
    48     return 1;
    49 }
    50 int main(){
    51     cin>>n;
    52     for(int i=1;i<=n;i++){
    53         cin>>s[i];
    54         insert(i);
    55     }
    56     for(int i=1;i<=n;i++){
    57         if(query(i)) ans[++num]=i;
    58     }
    59     cout<<num<<endl;
    60     for(int i=1;i<=num;i++) cout<<s[ans[i]]<<endl;
    61     return 0;
    62 }
  • 相关阅读:
    数据库原理与应用-------------触发器和视图
    Python操作SQLServer示例
    基于python的图片修复程序-可用于水印去除
    Android APK反编译就这么简单 详解
    android官网文档学习笔记
    android散点技术
    读书笔记一
    eclipse的各种错误和解决方法
    css
    响应式设计
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14260213.html
Copyright © 2011-2022 走看看