简介:
给出一个字符串集合S,定义P(S)为所有字符串的公共前缀长度*|S|
给定n个01串,从中选出一个集合S,使P(S)最大
分析:
这就是Trie的经典题啦
我们把所有的串都扔到一个Trie上,同时统计每个结点上有多少字符串,
然后一遍dfs得出答案(结点的deep就是LCP的长度)
这道题我还是用的左儿右兄的记录方式
感觉不是一般的方便啊
一般需要记录字符集的问题,都可以考虑用Trie
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=1000010;
struct Trie{
int son[N];
int nxt[N];
int tot[N];
char ch[N];
int cnt,maxx;
void init()
{
memset(son,0,sizeof(son));
memset(nxt,0,sizeof(nxt));
memset(tot,0,sizeof(tot));
cnt=0;
}
void insert(char *s)
{
int now,pre=0;
int len=strlen(s);
tot[0]++;
for (int i=0;i<len;i++)
{
bool ff=0;
for (now=son[pre];now;now=nxt[now])
if (ch[now]==s[i]) {ff=1;break;}
if (!ff)
{
now=++cnt;
nxt[now]=son[pre];
son[pre]=now;
ch[now]=s[i];
}
pre=now;
tot[pre]++;
}
}
void dfs(int now,int dep)
{
maxx=max(maxx,dep*tot[now]);
for (int i=son[now];i;i=nxt[i])
dfs(i,dep+1);
}
void count()
{
maxx=0;
dfs(0,0);
printf("%d\n",maxx);
}
};
Trie trie;
int n;
int main()
{
char s[203];
int T;
scanf("%d",&T);
while (T--)
{
trie.init();
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%s",&s);
trie.insert(s);
}
trie.count();
}
return 0;
}