POJ 3630 Phone List(字典树)

题意

题意:t个case(1<=t<=40),给你n个电话号码(电话号码长度<10)(1 ≤ n ≤ 10000),如果有电话号码是另一个电话号码的前缀,则称这个通讯录是不相容的,判断通讯录是否相容。

题解

把电话的结尾做标记,check的过程中,如果是电话号码的结尾并且trie树后面还有枝子,输出NO。(对树DFS一下)

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=200010;
 8 int t,n,tot;
 9 char s[N];
10 struct tree{
11     int nxt[30],e,h;
12 }tr[N];
13 void insert(char s[]){
14     int len=strlen(s);
15     int now=0;
16     for(int i=0;i<len;i++){
17         if(!tr[now].nxt[s[i]-'0']){
18             tr[now].h=1;
19             tr[now].nxt[s[i]-'0']=++tot;
20         }
21         now=tr[now].nxt[s[i]-'0'];
22     }
23     tr[now].e++;
24 }
25 bool dfs(int u){
26     if((tr[u].e&&tr[u].h)||(tr[u].e>1))return true;
27     for(int i=0;i<=9;i++){
28         if(tr[u].nxt[i]){
29             if(dfs(tr[u].nxt[i]))return true;
30         }
31     }
32     if(u==0)return false;
33 }
34 void clear(int u){
35     for(int i=0;i<=9;i++){
36         if(tr[u].nxt[i])clear(tr[u].nxt[i]);
37     }
38     memset(tr[u].nxt,0,sizeof(tr[u].nxt));
39     tr[u].e=tr[u].h=0;
40 }
41 int main(){
42     scanf("%d",&t);
43     while(t--){
44         scanf("%d",&n);
45         tot=0;
46         for(int i=1;i<=n;i++){
47             scanf("%s",s);
48             insert(s);
49         }
50         if(dfs(0))printf("NO\n");
51         else printf("YES\n");
52         clear(0);
53     }
54     return 0;
55 }

 

posted @ 2018-08-19 09:52  Xu-daxia  阅读(114)  评论(0编辑  收藏  举报