如圖所示:
每個字元有很多個分支,打黃色標記的就是字串的結尾,所以這顆字典樹中有哪些字串呢,"ab","ay","ayf","c","cc","cd",其他的枝沒有畫全。
順序儲存字串:「
ab」「
ay」「
ayf」「c」「
cc」「cd」
……(節點編號講究先到先得)
陣列tree[
i][j]:代表i
節點的第
j個兒子的節點編號。(獲取第幾個孩子可以s[i]-'a',以圖中5節點舉例,就是tree[0][2]=5) 陣列
flag[i]:
為true
代表到該節點為乙個字串
#includeusing namespace std;
const int maxn=2e6+5;
int tree[maxn][30],tot=0;
bool flag[maxn];
void add(char *s)
if(!flag[root]) ans++;
flag[root]=1;
}int main()
cout結合set也很簡單;
#includeusing namespace std;
int main()
cout<題目大意:求能代表字串的最小字首,獨一無二,沒有歧義的。
解題思路:用sum[root]記錄每個節點的數量,只要在find時候走到sum[root]==1的時候說明只有該字串到過這,那麼返回字串就可以了。
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e6+5;
int tree[maxn][30];
bool flag[maxn];
int tot=0,sum[maxn];
void add(char *s)
if(tp==len) return false;
else return true;
}int main()
if(tree[root][26])
} if(tree[root][27])
id=s[pos]-'a';
if(s[pos]>='a'&&s[pos]<='z'&&tree[root][id])
}char tp[50];
int main()
for(int i=0;i=2)
} } for(auto it=ans.begin();it!=ans.end();++it)
if(!vis[root]) vis[root]=++cnt;
return vis[root];
}void init()
}int find(int x)
void unite(int x,int y)
}char s1[20],s2[20];
int main()
int flag=find(1),tt=0;
for(int i=1; i<=cnt; ++i)
} if(tt==0||tt==2) cout<
else cout<
return 0;
}
字典樹 例題
給定 n個長度不超過10的數字串,問其中是否存在兩個數字串 s t,使得 s是 t的字首,多組資料。輸入格式 第一行乙個整數 t,表示資料組數。對於每組資料,第一行乙個數n,接下來 n行輸入 n個數字串。輸出格式 對於每組資料,若存在兩個數字串 s t,使得 s是 t的字首,則輸出 no 否則輸出 ...
字典樹 例題
關於學習字典樹,可以轉步這篇文章傳送門 例題1 poj3630 hdu 1671 這裡要在插入時候進行檢驗是否存在某個號碼是已存在號碼的字首或者存在某個號碼是當前插入號碼 的字首。先說hdu1671,因為poj的使用動態建樹給tle了,所以要用靜態建樹,這裡先說動態建樹 hdu1671 感覺可以做模...
Trie字典樹例題
前幾天做了個trie樹的題,正好記一下。首先先看乙個簡單題 acwing 143.最大異或對 題目 在給定的n個整數a1,a2 an中選出兩個進行 xor 異或 運算,得到的結果最大是多少?第一行輸入乙個整數n。第二行輸入n個整數a1 an。輸出乙個整數表示答案。1 n 105 0 a i 23 1...