Question: http://blog.csdn.net/u013480600/article/details/23122503
My code has been TLE, and, after reading someone else, I think 1. chained forward star is better. 2. * depth is not calculated every time a node exists. This is good.
I basically copy other people's code, add comments myself, leave a mark, and then rewrite it,
This question is also used as a trie template for chain forward stars.
# Include <cstdio> # include <cstring> # include <iostream> using namespace STD; # define ll long longconst int maxn = 4002*1002 + 100; struct trie {int head [maxn]; // its value is the subscript int next [maxn] In the edge set; // next [J] The subscript int tot [maxn] of the next edge of entry J in the edge set; char STR [maxn]; // It is equivalent to the upper bound of the bottom mark of the edge storage character int SZ; // It is also equivalent to the node ll ans; void clear () {ans = 0; SZ = 1; head [0] = next [0] = tot [0] = 0;} void insert (char * s) {int n = strlen (s), u = 0; TOT [u] ++; For (INT I = 0; I <= N; I ++) // empty characters are also inserted {bool found = false; For (Int J = head [u]; J; j = next [J]) if (STR [J] = s [I]) {u = J; found = true; break;} If (! Found) // The node does not exist {next [SZ] = head [u]; head [u] = SZ; head [SZ] = 0; // tot [SZ] = 0; // The new node does not have an edge STR [SZ] = s [I]; // initialize the edge information. The side stores the character u = SZ ++; // U stores new subnodes} tot [u] ++;} void DFS (int dep, int U) {If (! Head [u]) // reaches the leaf node {ans + = tot [u] * (TOT [u]-1) * Dep;} else {int sum = 0; for (INT v = head [u]; V = next [v]) // ** sum + = tot [v] * (TOT [u]-tot [v]); // ** ans + = sum/2 * (DEP * 2 + 1); // I did not think of it here ,,,, in fact, you can calculate for (INT v = head [u]; V = next [v]) DFS (DEP + 1, v) ;}} ll CAL () {ans = 0; DFS (1000); Return ans ;}}; trie; char word [100 +]; int main () {int icase = 0, N; while (scanf ("% d", & N) {trie. clear (); For (INT I = 0; I <n; I ++) {scanf ("% s", word); trie. insert (Word);} printf ("case % d: % LLD \ n", ++ icase, trie. cal ();} return 0 ;}
My TLE code will be modified later
# Include <cstdio> # include <cstring> # include <iostream> using namespace STD; # define ll long longconst int n = 4011*1000 + 10; const int TK = 75; const int TB = '0'; // TK cross; Start letter: Tb; int top, tree [N] [TK + 2]; // n: Maximum node count top: number of nodes in the first layer char STR [1010]; void Init () {Top = 1; memset (tree [0], 0, sizeof (tree [0]);} void insert (char * s, int Rank = 1) {int RT, NXT; For (RT = 0; * s; RT = NXT, ++ S) {NXT = tree [RT] [* s-TB]; If (0 = NXT) {// insert tree [RT] [* s-TB] = NXT = top; memset (tree [Top], 0, sizeof (tree [Top]); top ++;} tree [NXT] [TK] ++; // its value indicates how many words have passed through.} tree [RT] [TK + 1] = rank; // 1 indicates that 0 indicates that no word exists, you can also give it other meanings} ll solve (int rt, int last) {If (tree [RT] [TK] <= 1) return 0; // you only need to compare once at the end. If there is only one, you only need to compare ll ans = 0; For (INT I = 0; I <TK; I ++) if (tree [RT] [I]) {ans = ans + tree [tree [RT] [I] [TK] * (last-tree [tree [RT] [I] [TK]); // calculate the subtree forest} ANS/= 2; for (INT I = 0; I <TK; I ++) {If (tree [RT] [I]) {ans + = solve (tree [RT] [I], tree [tree [RT] [I] [TK]);} // return ans + 2 * C [tree [RT] [TK] [2]; return ans + tree [RT] [TK] * (tree [RT] [TK]-1);} int main () {freopen ("uva11732.txt", "r ", stdin); int icase = 0, N, Len; // calc (); While (scanf ("% d", & n) = 1 & N) {Init (); tree [0] [TK] = N; For (INT I = 0; I <n; I ++) {scanf ("% s ", str); insert (STR);} printf ("case % d: % LLD \ n", ++ icase, solve (0, n) -N * (n-1);} return 0 ;}