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. 在VS2012中设置默认启动

    Visual Studio 2012一个解决方案中多个项目,如果想选择哪个项目就设置哪个项目为启动项就好了. 第一种方法,工具===〉〉选项===〉〉〉项目解决方案===〉〉〉对于新的解决方案,使用单 ...

  2. CTSC2018 & APIO2018 颓废 + 打铁记

    CTSC2018 & APIO2018 颓废 + 打铁记 CTSC 5 月 6 日 完美错过报道,到酒店领了房卡放完行李后直接奔向八十中拿胸牌.饭票和资料.试机时是九省联考的题,从来没做过,我 ...

  3. 洛谷 P2529 [SHOI2001]击鼓传花 解题报告

    P2529 [SHOI2001]击鼓传花 题意:求出\(n!\)末尾最后一位非0数字 数据范围:\(n<=10^{100}\) 我们从简单的开始考虑 1.显然,\(n!\)可以被这么表示 \(n ...

  4. 【CF edu 30 C. Strange Game On Matrix】

    time limit per test 1 second memory limit per test  256 megabytes input standard input output standa ...

  5. 【BZOJ 4198】[Noi2015]荷马史诗 哈夫曼编码

    合并果子加强版....... 哈夫曼树是一种特别的贪心算法,它的作用是使若干个点合并成一棵树,每次合并新建一个节点连接两个合并根并形成一个新的根,使叶子节点的权值乘上其到根的路径长的和最短(等价于每次 ...

  6. Linux(CentOS)用split命令分割文件

    在 Linux 里,稍加不注意有可能会产生很大体积的日志文件,哪怕几百M,拖下来分析也很浪费时间,这个时候,如果可以把文件切割成 N 个小文件,拿最后一个文件就可以看到最近的日志了.有一些手段,比如用 ...

  7. BZOJ1001:狼抓兔子(最小割最大流+vector模板)

    1001: [BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨, ...

  8. hive subprocess failed with code X 的错误码对应信息

    PipeMapRed.waitOutputThreads(): subprocess failed with code X ,这里code X对应的信息如下:error code 1: Operati ...

  9. Drac6-Web界面无法访问

    1. ssh idracip, and reset RAC -- will need around 10mins /admin1-> racadm racreset RAC reset oper ...

  10. MyEclipse中代码提醒功能

    一:最近仔细研究了下spring mvc中的代码,自己在配置文件哪里来时出现问题,没有提醒,只好自己搜了下有关的信息.如下 window--->preferences---->java-- ...