trie树,儿子兄弟表示法+uva11732
2014-02-23 22:05
323 查看
题意:给出n个字符串,进行两两比较,计算比较的次数。
刚开始用指针写,发现这样写保存信息的时候不好计算,于是学习刘汝佳的儿子兄弟表示,这样建树统计分差点的比较次数是非常方便。
刚开始用指针写,发现这样写保存信息的时候不好计算,于是学习刘汝佳的儿子兄弟表示,这样建树统计分差点的比较次数是非常方便。
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; const int maxn=4000*1000*10; int n; struct trie { int head[maxn];//第一个孩子节点编号 int next[maxn];//兄弟编号 int tot[maxn];//经过这个节点的字符串数量 char ch[maxn]; int sz; long long ans; void clear(){sz=1;ans=0;head[0]=next[0]=tot[0]=0;} void insert(char * a) { int u=0,v,len=strlen(a); tot[0]++; for(int i=0;i<=len;i++) { bool found=false; for(v=head[u];v!=0;v=next[v]) { if(ch[v]==a[i]) { found=true; break; } } if(!found)//找不到,新建节点 { v=sz++; tot[v]=0; next[v]=head[u]; head[u]=v; ch[v]=a[i]; head[v]=0; } u=v; tot[u]++; } } void dfs(int depth,int u) { if(head[u]==0) { ans+=tot[u]*(tot[u]-1)*depth; return; } int sum=0; for(int v=head[u];v!=0;v=next[v]) sum+=tot[v]*(tot[u]-tot[v]); ans+=sum/2*(depth*2+1); for(int v=head[u];v!=0;v=next[v]) dfs(depth+1,v); } long long count() { ans=0; dfs(0,0); return ans; } }tree; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int t=1; while(scanf("%d",&n)!=EOF,n) { char a[4010]; tree.clear(); for(int i=0;i<n;i++) { scanf("%s",a); tree.insert(a); } printf("Case %d: %lld\n",t++,tree.count()); } return 0; }
相关文章推荐
- UVa 11732 strcmp函数 trie树 左儿子右兄弟表示法
- 左儿子有兄弟trie树
- UVA 11732 strcmp() Anyone? Trie的左儿子右兄弟表示法
- UVA 11732 —— 左儿子右兄弟表示法&&Tire
- 普通树转二叉树:左儿子右兄弟表示法
- UVA 11732 "strcmp()" Anyone? Trie树 + 树的左儿子右兄弟存储法
- 树的左儿子右兄弟表示法
- trie树 和 树的存储--左儿子右兄弟 --- uva 11732
- (uva 11732) "strcmp()" Anyone? (trie+左儿子右兄弟表示法)
- UVA 11732-"strcmp()" Anyone?-trie(左儿子右兄弟表示法(省空间))
- UVA 11732 "strcmp()" Anyone(字典树+左儿子-右兄弟表示法)
- uva 11732 "strcmp()" Anyone? (trie+左儿子右兄弟表示法)
- 左儿子右兄弟表示法
- UVa11732 "strcmp()" Anyone?(Trie树+孩子兄弟表示法)
- jq 取得父亲兄弟儿子的值
- trie树的 表示方法和实现
- 树的左孩子 右兄弟表示法的建立过程 (后序遍历)
- UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie
- 软件设计师2006年11月下午试题5(C语言 树及其孩子-兄弟表示)
- B树插入向一个已经有M项的节点添加元素,则在分裂该节点以前要执行搜索具有少于M个儿子的兄弟的工作