UVa11488

来源:互联网 发布:mac 下载ubuntu镜像 编辑:程序博客网 时间:2024/06/05 15:47

题目链接

简介:
给出一个字符串集合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;}