HUST-1350 Trie
1350 - Trie
时间限制:1秒 内存限制:128兆
- 题目描述
- 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的更多相关文章
- 【LA3942-Remember the word 】Trie
http://acm.hust.edu.cn/vjudge/problem/22109 题意:给定n个单词,一个字符串,问把这个字符串划分为若干个单词的连接(单词可重复使用)有多少种方案(mod200 ...
- 【hdu1251-统计难题】Trie
http://acm.hust.edu.cn/vjudge/problem/16379 题意:给定多个单词,多次询问符合某前缀的单词有多少个. 题解:tire.数组开了5*10^6才A,不然就RE. ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- hihocoder-1014 Trie树
hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
- Poj The xor-longest Path 经典题 Trie求n个数中任意两个异或最大值
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5646 Accepted: 1226 Description In an ...
- 二分+DP+Trie HDOJ 5715 XOR 游戏
题目链接 XOR 游戏 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
随机推荐
- [org.hibernate.engine.jdbc.spi.SqlExceptionHelper]SQL Error: 1064, SQLState: 42000问题的解决办法
[org.hibernate.engine.jdbc.spi.SqlExceptionHelper]SQL Error: 1064, SQLState: 42000问题的解决办法. 出现这种情况的原因 ...
- 【历史】- .NET之父 - Anders Hejlsberg
简介 安德斯·海尔斯伯格(Anders Hejlsberg,1960.12~),丹麦人,Turbo Pascal编译器的主要作者,Delphi和.NET之父! 安德斯·海尔斯伯格曾在丹麦技术大学学习工 ...
- ArcGis融合小多边形到相邻多边形
在有的时候,我们的数据中可能会有许多细小的图斑,这些并不是我们想要的,需要将它们合并到周围的图斑中,如果一个一个手动合并,那工作量之大简直不敢想象.现在借助ArcGIS的Eliminate工具可 ...
- Java语言常用的运算符和表达式详解
Java提供了丰富的运算符,如算术运算符.关系运算符.逻辑运算符.位运算符等等.Java的表达式就是用运算符连接起来的符合Java规则的式子.运算符的优先级决定了表达式中运算执行的先后顺序.在编写程序 ...
- JSON教程(1)
JSON:JavaScript对象表示发即JavaScript Object Notation. JSON是存储和交换文本信息的语法.类似XML. JSON比XML更小,更快,更易解析. { &quo ...
- null?对象?异常?到底应该如何返回错误信息
这篇文章记录我的一些思考.在工作了一段时间之后. 问题的核心很简单:到底如何返回错误信息. 学生时代,见到过当时的老师的代码: if (foo() == null) { } 当然,这位老师是一位比较擅 ...
- [POJ1784]Huffman's Greed
题面在这里 题意 给出一棵\(n\)个节点的二叉查找树的中序遍历中每个节点的访问次数\(p[i]\),和相邻两节点\(i\)和\(i+1\)的访问次数\(q[i]\),构造一棵二叉查找树使得\(\su ...
- [bzoj1052] [HAOI2007]覆盖问题
Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L * L的正方形塑料薄膜 ...
- [USACO Hol10] 臭气弹 图上期望概率dp 高斯
记住一开始和后来的经过是两个事件因此概率可以大于一 #include<cstdio> #include<iostream> #include<cstdlib> #i ...
- The 13th Zhejiang Provincial Collegiate Programming Contest - I
People Counting Time Limit: 2 Seconds Memory Limit: 65536 KB In a BG (dinner gathering) for ZJU ...