hihocoder 1036 (Trie图)

题目链接

AC代码:

  1 #include<set>

  2 #include<map>

  3 #include<cmath>

  4 #include<queue>

  5 #include<cstdio>

  6 #include<vector>

  7 #include<string>

  8 #include<cstdlib>

  9 #include<cstring>

 10 #include<iostream>

 11 #include<algorithm>

 12 using namespace std;

 13 

 14 #define mem(a, b) (memset(a, b, sizeof(a)))

 15 #define pb push_back

 16 #define all(v) v.begin(), v.end()

 17 #define rall(v) v.rbegin(), v.rend()

 18 #define rep(i, m) for (int i = 0; i < (int)(m); i++)

 19 #define rep2(i, n, m) for (int i = n; i < (int)(m); i++)

 20 typedef long long LL;

 21 typedef pair<int, int> pii;

 22 

 23 const int oo = (int) 1e9;

 24 const double PI = 2 * acos(0);

 25 const double eps = 1e-9;

 26 const int MAX_N = 1000010;

 27 

 28 struct TrieNode {

 29     TrieNode *next[26]; // 若有子节点,则为子节点,否则为该节点后缀指向节点

 30     TrieNode *suffix;

 31     bool marked;

 32     TrieNode() {

 33         for (int i = 0; i < 26; ++i) {

 34             next[i] = NULL;

 35         }

 36         suffix = NULL;

 37         marked = false;

 38     }

 39 };

 40 

 41 struct TrieGragh {

 42     TrieNode *root;

 43     TrieGragh() { // 略去析构函数

 44         root = new TrieNode;

 45         root->suffix = root;

 46     }

 47 

 48     void insert(const char *s) {

 49         int pos = 0;

 50         TrieNode *nodePos = root;

 51         int sz = strlen(s);

 52         while (pos < sz) {

 53             int id = s[pos] - 'a';

 54             if (nodePos->next[id] == NULL) {

 55                 nodePos->next[id] = new TrieNode;

 56             }

 57             nodePos = nodePos->next[id];

 58             ++pos;

 59         }

 60         nodePos->marked = true;

 61     }

 62 

 63     void generateNext() {

 64         queue<TrieNode *> nodeQueue;

 65         for (int i = 0; i < 26; ++i) {

 66             if (root->next[i] != NULL) { // 初始化

 67                 nodeQueue.push(root->next[i]); // 子节点

 68                 root->next[i]->suffix = root;

 69                 if (root->marked)

 70                     root->next[i]->marked = true;

 71             } else {

 72                 root->next[i] = root;

 73             }

 74         }

 75 

 76         while (!nodeQueue.empty()) {

 77             TrieNode *node = nodeQueue.front();

 78             nodeQueue.pop();

 79 

 80             // 对于该节点,每个子节点压入队列并求后缀

 81             // 若父节点通过ch指向子节点,则子节点后缀 = 父节点后缀通过ch指向的节点

 82             for (int i = 0; i < 26; ++i) {

 83                 TrieNode *child = node->next[i];

 84                 if (child == NULL) {

 85                     node->next[i] = node->suffix->next[i];

 86                     continue;

 87                 }

 88                 child->suffix = node->suffix->next[i];

 89                 if (child->suffix->marked) // 后缀节点为已标记节点的节点也要标记

 90                     child->marked = true;

 91                 if (!child->marked) // 已标记节点的子节点无需再看

 92                     nodeQueue.push(child);

 93             }

 94         }

 95     }

 96 };

 97 

 98 bool match(TrieGragh *trieGragh, char *article) {

 99     int pos = 0;

100     TrieNode *nodePos = trieGragh->root;

101     if (nodePos->marked)

102         return true;

103     int sz = strlen(article);

104     while (pos < sz) {

105         int id = article[pos] - 'a';

106         if (id < 0 || id > 26) {

107             nodePos = trieGragh->root;

108             ++pos;

109             continue;

110         }

111         nodePos = nodePos->next[id];

112         if (nodePos->marked)

113             return true;

114         ++pos;

115     }

116     return false;

117 }

118 

119 char str[MAX_N];

120 int main(void) {

121     int N;

122     scanf("%d", &N);

123     TrieGragh *trieGragh = new TrieGragh;

124     for (int i = 0; i < N; ++i) {

125         scanf("%s", str);

126         trieGragh->insert(str);

127     }

128 

129     trieGragh->generateNext();

130     scanf("%s", str);

131     if (match(trieGragh, str))

132         printf("YES\n");

133     else

134         printf("NO\n");

135 

136     return 0;

137 }
View Code

 

你可能感兴趣的:(code)