1350 - Trie

时间限制:1秒 内存限制:128兆

104 次提交 35 次通过
题目描述
In computer science, a trie, is an ordered tree data structure that is used to store an associative array where the keys are usually strings. Each position in the tree shows what key it is associated with and All the descendants of a node have a common prefix of the string associated with that node, have and only have one more character than its father node. the root of the trie is associated with the empty string. For example, if we put 6 words of “to”, “tea”, “ted”, “ten”, “a”, “inn” to a trie, it will be the form of figure.  In the computer science, a trie is a tree. For a tree, we define the leave node is the node without any descendants and only have an edge connect in. So in this example, the leave node is “to”, “tea”, “ted”, “ten”, “a” and “inn”. And we define the distance between two node is the minimum edge from a node to another node must pass. So the distance between “a” and “te” is 3, “to” and “inn” is 5. Finally, we define the value of a node is the sum of the node to the entire leave node’s distance. And the value of a tree is equal the value of a node which have the minimum value. Now give you a list of words. Put them into a trie, and calculate the value of this trie.
输入
The first line is T, indicate there are T cases. For each case, the first line is N, indicate there are N words. Next N lines, each line have a word only include the lower case letters and no two words are the same. (N<=50 and the length of a word less than 10)
输出
For each case output a line with the value of the trie.
样例输入
2
6
a
to
tea
ted
ten
inn
4
sa
sb
sc
sd
样例输出
Case #1: 13
Case #2: 5 /////////////////////////////////////
For the second case, if the root has only one child, it’s a special leaf and must be calculate.
提示
来源
Hong Zehua, HUST Campus 2009
/**
题意:给几个字符串,构成一个字典树,求哪个节点到每个叶子的距离最短的,最短是多少
做法:先建立一个字典树,然后求公共祖先(求得是所有点到叶子节点的最短的距离)
**/
#include <iostream>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define maxn 100010
int tot = ;
const int MAXN = ;
const int DEG = ;
int num[maxn];
int tot2 = ;
int tot3 = ;
int num1[maxn];
int indegree[maxn];
int mmap[maxn];
int mm = ;
struct Node
{
int x;
int y;
int flag;
Node() {};
Node(int _x, int _y) {
x = _x;
y = _y;
flag = ;
}
} node[maxn << ];
struct Trie
{
int next[maxn][], end[maxn];
int root;
int L;
int newnode() {
for(int i = ; i < ; i++) {
next[L][i] = -;
}
end[L++] = ;
return L - ;
}
void init() {
L = ;
root = newnode();
}
void insert(char buf[]) {
int len = strlen(buf);
int now = root;
for(int i = ; i < len; i++) {
if(next[now][buf[i] - 'a'] == -) {
next[now][buf[i] - 'a'] = newnode();
node[tot].y = next[now][buf[i] - 'a'] + ;
node[tot].x = now + ;
node[tot].flag = ;
tot++;
}
now = next[now][buf[i] - 'a'];
}
node[tot - ].flag = ;
num[tot2++] = node[tot - ].y;
end[now]++;
}
};
Trie ac;
struct Edge
{
int to;
int next;
} edge[MAXN * ];
int head[MAXN], tot1;
void addedge(int u, int v)
{
edge[tot1].to = v;
edge[tot1].next = head[u];
head[u] = tot1++;
}
void init()
{
tot1 = ;
memset(head, -, sizeof(head));
}
int fa[MAXN << ][DEG];
int deg[MAXN << ];
void bfs(int root)
{
queue<int>que;
deg[root] = ;
fa[root][] = root;
que.push(root);
while(!que.empty())
{
int tmp = que.front();
que.pop();
for(int i = ; i < DEG; i++) {
fa[tmp][i] = fa[fa[tmp][i - ]][i - ];
}
for(int i = head[tmp]; i != -; i = edge[i].next)
{ int v = edge[i].to;
if(v == fa[tmp][]) {
continue;
}
deg[v] = deg[tmp] + ;
fa[v][] = tmp;
que.push(v);
}
}
}
int LCA(int u, int v)
{
if(deg[u] > deg[v]) {
swap(u, v);
}
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for(int det = hv - hu, i = ; det; det >>= , i++)
if(det & ) {
tv = fa[tv][i];
}
if(tu == tv) {
return tu;
}
for(int i = DEG - ; i >= ; i--)
{
if(fa[tu][i] == fa[tv][i]) {
continue;
}
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][];
}
bool flag[MAXN];
char buf[];
int main()
{
//freopen("in.txt", "r", stdin);
int Case = ;
int T;
scanf("%d", &T);
while(T--)
{
int n;
tot = ; ///边的数目
tot2 = ; ///叶子节点的数目 如果根节点存在Case 2 中的情况也加进去
tot3 = ; ///不是叶子的节点的节点
mm = ;
memset(node, , sizeof(node));
memset(indegree, , sizeof(indegree));
memset(flag, , sizeof(flag));
scanf("%d", &n);
ac.init();
for(int i = ; i < n; i++)
{
scanf("%s", buf);
ac.insert(buf);
}
init();
int yy = ;
for(int i = ; i < tot; i++)
{
addedge(node[i].x, node[i].y);
addedge(node[i].y, node[i].x);
indegree[node[i].x] ++;
indegree[node[i].y] ++;
yy = max(yy, max(node[i].x, node[i].y));
}
for(int i = ; i < tot; i++) {
if(indegree[node[i].x] == ) {
mmap[mm++] = node[i].x;
}
else {
num1[tot3++] = node[i].x;
}
if(indegree[node[i].y] == ) {
mmap[mm++] = node[i].y;
}
else {
num1[tot3++] = node[i].y;
}
}
sort(mmap, mmap + mm);
sort(num1, num1 + tot3);
int newmm = unique(mmap, mmap + mm) - mmap;
int newtot3 = unique(num1, num1 + tot3) - num1;
bfs();
int mmin = 0xfffffff;
for(int i = ; i <= yy; i++)
{
int temp = ;
for(int j = ; j < newmm; j++)
{
if(i != mmap[j]) {
int tt = LCA(i, mmap[j]);
int res = ;
res = abs(deg[i] - deg[tt]) + abs(deg[mmap[j]] - deg[tt]);
temp += res;
}
}
mmin = min(mmin, temp);
}
printf("Case #%d: %d\n", Case++, mmin);
}
return ;
}

HUST-1350 Trie的更多相关文章

  1. 【LA3942-Remember the word 】Trie

    http://acm.hust.edu.cn/vjudge/problem/22109 题意:给定n个单词,一个字符串,问把这个字符串划分为若干个单词的连接(单词可重复使用)有多少种方案(mod200 ...

  2. 【hdu1251-统计难题】Trie

    http://acm.hust.edu.cn/vjudge/problem/16379 题意:给定多个单词,多次询问符合某前缀的单词有多少个. 题解:tire.数组开了5*10^6才A,不然就RE. ...

  3. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  4. 基于trie树的具有联想功能的文本编辑器

    之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...

  5. [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  6. hihocoder-1014 Trie树

    hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...

  7. 【BZOJ-2938】病毒 Trie图 + 拓扑排序

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 609  Solved: 318[Submit][Status][Di ...

  8. Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5646   Accepted: 1226 Description In an ...

  9. 二分+DP+Trie HDOJ 5715 XOR 游戏

    题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

随机推荐

  1. UVA 437 The Tower of Babylon(DAG上的动态规划)

    题目大意是根据所给的有无限多个的n种立方体,求其所堆砌成的塔最大高度. 方法1,建图求解,可以把问题转化成求DAG上的最长路问题 #include <cstdio> #include &l ...

  2. C++-STL:vector用法总结

    目录 简介 用法 1. 头文件 2. vector的声明及初始化 3. vector基本操作 简介 vector,是同一类型的对象的集合,这一集合可看作可变大小的数组,是顺序容器的一种.相比于数组,应 ...

  3. java文件的I/O

    [原创] java文件的I/O操作,简单来说就是向文件中写入数据以及从文件中读出数据,这是我们平日做的最多的操作,这里给出两种文件I/O操作,当然还有许多的操作方法,各种流的使用,可谓是高深莫测:不管 ...

  4. 浅谈c语言和c++中struct的区别

    今天做二叉树的时候,发现利用结构体有点乱,不知道怎么回事,我之前知道c语言中声明一个结构体变量时需要通过 struct 结构体名 变量名,而在c++中,可以不要struct,由于可以利用typedef ...

  5. 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有 多少总跳法?

    首先我们考虑最简单的情况:如果只有1 级台阶,那显然只有一种跳法,如果有2 级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1 级:另外一种就是一次跳2 级.现在我们再来讨论一般情况:我们把n 级 ...

  6. 算法(10)Subarray Sum Equals K

    题目:在数组中找到一个子数组,让子数组的和是k. 思路:先发发牢骚,这两天做题是卡到不行哇,前一个题折腾了三天,这个题上午又被卡住,一气之下,中午睡觉,下午去了趟公司,竟然把namespace和cgr ...

  7. Vim使用小记(一)常用操作

    By francis_hao    Sep 22,2016 vim的功能自然不止如此,这里只是把日常使用频率较高的记录下来,若想了解vim的全部功能可查阅其帮助手册:help,或者查询指定命令的用法: ...

  8. CentOS 6.4安装配置ldap

    CentOS 6.5安装配置ldap 时间:2015-07-14 00:54来源:blog.51cto.com 作者:"ly36843运维" 博客 举报 点击:274次 一.安装l ...

  9. AWS文档与用户指南

    AWS Command Line Interface http://docs.amazonaws.cn/cli/latest/userguide/cli-chap-welcome.html VM Im ...

  10. 关于JAVA正则匹配空白字符的问题(全角空格与半角空格)

    今天遇到一个字符串,怎么匹配空格都不成功!!! 我把空格复制到test.properties文件 显示“\u3000” ,这是什么? 这是全角空格!!! 查了一下    \s    不支持全角 1.& ...