E - Shortest Names
Time Limit:1000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Submit
Status
Description
Shortest Names
In a strange village, people have very long names. For example: aaaaa, bbb and abababab.
You see, it's very inconvenient to call a person, so people invented a good way: just call a prefix of the names. For example, if you want to call `aaaaa', you can call `aaa', because no other names start with `aaa'. However, you can't call `a', because two people's names start with `a'. The people in the village are smart enough to always call the shortest possible prefix. It is guaranteed that no name is a prefix of another name (as a result, no two names can be equal).
If someone in the village wants to call every person (including himself/herself) in the village exactly once, how many characters will he/she use?
Input
The first line contains T (T10), the number of test cases. Each test case begins with a line of one integer n ( 1n1000), the number of people in the village. Each of the following n lines contains a string consisting of lowercase letters, representing the name of a person. The sum of lengths of all the names in a test case does not exceed 1,000,000.
Output
For each test case, print the total number of characters needed.
Sample Input
1
3
aaaaa
bbb
abababab
Sample Output
5
Problemsetter: Rujia Liu, Special Thanks: Yiming Li, Feng Chen, Jane Alam Jan
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=100000;
struct Trie
{
int tot,root,ch[maxn][27];
bool flag[maxn];
int rk[maxn];
Trie()
{
memset(ch[1],0,sizeof(ch[1]));
memset(rk,0,sizeof(rk));
flag[1]=false;
root=tot=1;
rk[1]=-1;
}
void Insert(const char*str)
{
int *cur=&root;
for(const char* p=str;*p;p++)
{
cur=&ch[*cur][*p-'a'];
rk[*cur]++;
if(*cur==0)
{
tot++;
*cur=tot;
memset(ch[tot],0,sizeof(ch[tot]));
flag[tot]=false;
rk[tot]++;
}
}
flag[*cur]=true;
}
int query(const char* str)
{
int first=1;
int cnt=0;
int *cur=&root;
for(const char *p=str;*p && *cur;p++)
{
cur=&ch[*cur][*p-'a'];
if(first)
{
if(rk[*cur]==1)
{
first=0;
}
else
{
cnt++;
}
}
}
//return (*cur&&flag[*cur]);
return cnt;
}
}tree[20];
char name[1010][10000];
int main()
{
int T;
cin>>T;
for(int t=0;t<T;t++)
{
int n;
cin>>n;
int sum=0;
for(int i=0;i<n;i++)
{
cin>>name;
tree[t].Insert(name);
}
for(int i=0;i<n;i++)
{
// cout<<name<<"--->"<<tree[t].query(name)<<endl;
sum+=tree[t].query(name);
}
/*
char str[10000];
while(cin>>str)
{
cout<<tree[t].query(str)<<endl;
}
*/
cout<<sum+n<<endl;
}
return 0;
}