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 }